如果我重载了原始的“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。如果被替换,那么不,你不能,但我相信这是 whymalloc
保证不会在其实现中使用 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()
c++ new operator和operator new,delete operator和operator delete
错误 C2661:“CObject::operator new”:没有重载函数需要 4 个与 Visual Studio 相关的参数