我有下面的代码
class Test
{
public:
Test(){}
Test(int i) {}
void* operator new (size_t size)
{
void *p = malloc(size);
return p;
}
//void* operator new (size_t size, Test *p)
//{
// return p;
//}
};
int main() {
Test *p = new Test;
int i = 10;
new(p) Test(i);
}
Run Code Online (Sandbox Code Playgroud)
上面的代码片段不能在visual studio中编译,除非我取消注释重载的放置新操作符函数.如果我注释掉正常重载的新内容,那么它也能正常工作.重载正常的新运算符时是否重载了新的必需项(如果需要为该类使用新的位置)
此处未显示展示位置删除相关代码.
通常不会,因为它不经常使用。但这可能是必要的,因为当您operator new在类中重载时,它会隐藏全局::operator new.
因此,如果您想在该类的对象上使用placement new,请执行以下操作:否则不要。新的也同样如此nothrow。
如果您刚刚更改了分配方案,并且您对某个地方有人在您背后使用新的放置感到惊讶,那么在应用此创可贴之前可能需要进行调查。
如果该类在标准库容器内使用,而不是直接与 一起使用new,则自定义分配方案应由 Allocator 类定义,而不是重载。默认分配器std::allocator不考虑成员operator new重载,而是绕过它们。见下文。
免责声明:类范围operator new重载主要用于调试,即使如此,获得可靠且有意义的语义也很困难。谨防:
你还需要超载operator delete。(本问题的示例中未完成。)
重载将被限定语法绕过::new T。您无法阻止此类绕过。这就是分配事物的方式std::allocator<T>。你可以专门std::allocator针对你的类型,但这已经是进入兔子洞的方式了。
对于::operator new任何库引入的每个重载,包括规范放置 new from <new>,您必须考虑它是否适用于您的类,并决定是否添加重载,或者以其他方式应对不合格new表达式的失败。
::operator new对于您在班级中采用的每个成员,您必须提供operator delete具有正确语义的相应成员位置。如果构造函数因异常退出,则调用此函数。如果没有它,只有在非常特定的情况下,在可能资源受限的池中,才会导致内存泄漏。
总之,成员operator new是防御性编码的对立面。