stroustroup 在他的《C++ 编程语言》(第 4 版)一书中提到,可以通过编写具有以下签名的全局函数来重载全局运算符 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
NOTE:为删除传递 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)似乎都有效!
正如我提到的注释中所解释的那样,在删除中传递 size_t 参数似乎是合乎逻辑的。但这种行为的原因可能是什么?我正在使用 VS2013 来测试示例。
来自 C++1y 草案:
5.3.5 删除[expr.delete]
[...]
11 当执行删除表达式时,应调用选定的释放函数,将要回收的存储块的地址作为其第一个参数,并且(如果使用两参数释放函数)将块的大小作为其第一个参数。第二个论点.83
脚注83)如果要删除的对象的静态类型完整且与动态类型不同,并且析构函数不
virtual,大小可能不正确,但如上所述,这种情况已经未定义。
17.6.4.6 替换函数[replacement.functions]
1 第 18 条至第 30 条以及附录 D 描述了 C++ 标准库定义的众多函数的行为。然而,在某些情况下,这些函数描述中的某些也适用于程序(17.3)中定义的替换函数。
2 C++ 程序可以提供头文件中声明的 12 个动态内存分配函数签名中的任何一个的定义<new>
(3.7.4、18.6):
operator new(std::size_t)
operator new(std::size_t, const std::nothrow_t&)
operator new[](std::size_t)
operator new[](std::size_t, const std::nothrow_t&)
perator delete(void*)
operator delete(void*, const std::nothrow_t&)
operator delete[](void*)
operator delete[](void*, const std::nothrow_t&)
我的注释:接下来的四个是 C++1y 中的新内容
operator delete(void*, std::size_t)
operator delete(void*, std::size_t, const std::nothrow_t&)
operator delete[](void*, std::size_t)
operator delete[](void*, std::size_t, const std::nothrow_t&)
3 使用程序的定义来代替实现 (18.6) 提供的默认版本。这种替换发生在程序启动之前(3.2、3.6)。程序的定义不得指定为内联。无需诊断。
另请看一下在 C++1y 中引入大小释放的提案:
http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3536.html
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)