【发布时间】:2014-07-16 00:05:16
【问题描述】:
在他的《C++ 编程语言》(第 4 版)一书中,stroustroup 提到可以通过编写具有以下签名的全局函数来重载全局运算符 new & delete:
void* operator new(size_t); // use for individual object
void* operator new[](size_t); // use for array
void operator delete(void*, size_t); // use for individual object
void operator delete[](void*, size_t); // use for array
注意: size_t 参数传递给删除以确定正确的对象大小,特别是在删除由基指针指向的派生对象时(基需要虚拟 dtor 以便传递正确的大小)。
我试图重载单个对象的全局版本。运算符 new 工作正常。具有上述签名的操作员删除工作正常,但删除不会被调用。如果我更改删除签名以便它只需要一个 void *,它就会被调用。可能是什么问题:
代码如下:
void * operator new (size_t size)
{
cout << "My operator new called\n";
auto p = malloc(size);
return p;
}
void operator delete (void * ptr, size_t size) // Removing size_t parameter makes it work
{
cout << "My operator delete called\n";
free(ptr);
}
奇怪的是,如果我让操作员删除一个类的成员,使其仅为该类重载,那么删除签名(带有 size_t 和不带 size_t)似乎都可以工作!
在 delete 中传递 size_t 参数似乎是合乎逻辑的,正如我提到的 NOTE 中所解释的那样。但这种行为的原因可能是什么?我正在使用 VS2013 来测试示例。
【问题讨论】:
-
感谢网络链接。那里的解释似乎表明删除的全局版本具有签名,该签名需要两个 void *,而特定于类的版本需要一个 void * 和一个 size_t。这与书中提到的相反。那么你是在暗示这是书中的一个错误吗?
-
仔细阅读。这些是您从帖子中选择的展示位置版本。
-
查看此操作员
delete可能的签名:en.cppreference.com/w/cpp/memory/new/operator_delete -
@Deduplicator Aaah...是的...所以全局的不需要 size_t。所以我想这本书有一个错误
标签: c++ operator-overloading new-operator