如果我重载了原始的“operator new”,如何调用它?

Posted

技术标签:

【中文标题】如果我重载了原始的“operator new”,如何调用它?【英文标题】:How do I call the original "operator new" if I have overloaded it? 【发布时间】:2011-05-07 06:13:22 【问题描述】:

假设我需要重载全局::operator new()for storing extra data with each allocated object。所以基本上它会这样工作:

对于全局::operator new() 的每次调用,它将获取传递的对象大小并添加额外数据的大小 它将分配一个内存块,其大小在上一步推导出来 它会将指针偏移到块中未被额外数据占用的部分,并将该偏移值返回给调用者

::operator delete() 将反向执行相同的操作 - 移动指针、访问额外数据、释放内存。

现在的问题是我如何分配内存?当然,我可以调用malloc() 或一些特定于平台的函数(通常是这样做的)。但通常当我需要在 C++ 中分配原始内存时,我会调用 ::operator new()。我可以调用原来的::operator new() 来从我重载的全局::operator new() 内部进行内存分配吗?

【问题讨论】:

你的意思是超载还是被替换?如果重载,只需使用正确的参数集调用原始运算符 new。如果被替换,那么不,你不能,但我相信这是 why malloc 保证不会在其实现中使用 operator new (即当 operator new 被替换时没有无意的循环)所以你可能应该使用malloc @CharlesBailey 您将答案写成评论!耻辱! 【参考方案1】:

您无法访问它们,因为它并没有真正超载,而是替换。当您定义自己的::operator new 时,旧的就消失了。差不多就是这样。

本质上,您需要从自定义::operator new 调用malloc。不仅如此,还要按照18.4.1.1/4中的说明正确处理错误:

默认行为:

——执行一个循环: 在循环内,函数首先 尝试分配请求的 贮存。尝试是否涉及 调用标准 C 库 函数 malloc 未指定。

—— 返回一个指向已分配的指针 如果尝试成功,则存储。 否则,如果最后一个参数 set_new_handler() 是一个空指针, 抛出 bad_alloc。

——否则, 函数调用当前的 new_handler (18.4.2.2)。如果调用函数 返回,循环重复。

——循环 当尝试分配时终止 请求的存储成功或 当调用 new_handler 函数时 不返回。

【讨论】:

别忘了把operator delete也换成free() 我相信 Scott Meyers 在他的 Effective C++ 书籍中详细讨论了这一点。第二版中的第 8 条,第三版中的第 8 章,看起来如此。 @Potatoswatter:他不能使用malloc() 为他的类和额外数据分配内存,然后调用placement-new 在这个内存中实例化类对象。既然他只是替换了new 的常规版本,不会调用默认的placement-new 吗? @Praetorian:这会起作用,但这将迫使我自己处理所有错误处理。例如 - 如果构造函数抛出怎么办? @Sharptooth:你可以把所有东西都放在try-catch 块中,清理分配的内存并重新抛出异常。

以上是关于如果我重载了原始的“operator new”,如何调用它?的主要内容,如果未能解决你的问题,请参考以下文章

C++内存管理机制学习笔记:重载operate new/::operator new..../new()

重载operator new delete函数

c++ new operator和operator new,delete operator和operator delete

C++ 内存分配(new,operator new)详解

错误 C2661:“CObject::operator new”:没有重载函数需要 4 个与 Visual Studio 相关的参数

STL 之 operator new 函数