gpt4 book ai didi

c++ - 当我们重载新运算符时,是否有必要重载放置新运算符?

转载 作者:可可西里 更新时间:2023-11-01 17:57:18 26 4
gpt4 key购买 nike

我有下面一段代码

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);
}

以上代码无法在 visual studio 中编译,除非我取消注释掉重载的 placement new 运算符函数。如果我注释掉正常的重载新的,在那种情况下它也可以正常工作。重载普通 new 运算符时是否必须重载 placement new(如果该类需要使用 placement new)

Placement删除相关的代码这里就不展示了。

最佳答案

通常不需要,因为它不经常使用。但这可能是必要的,因为当您重载 operator new 时在一个类中,它隐藏了全局 ::operator new 的所有重载.

因此,如果您想在该类的对象上使用 placement new,请这样做;否则不要。同样适用于 nothrow新的。

如果您刚刚更改了分配方案,并且您对某个地方的某个人在背后使用 placement new 感到惊讶,那么在应用此创可贴之前可能需要调查一下。

如果该类在标准库容器中使用,而不是直接使用 new ,自定义分配方案应该由 Allocator 类定义,而不是重载。默认分配器 std::allocator不尊重成员(member)operator new过载,但绕过它们。见下文。


免责声明:类作用域 operator new重载主要用于调试,即使这样也很难获得可靠有意义的语义。当心:

  • 你还需要重载 operator delete . (在这个问题的例子中没有完成。)

  • 重载将被限定语法绕过 ::new T .您无法阻止此类绕过。这就是std::allocator<T>的方式分配东西。你可以专攻std::allocator对于您的类型,但这已经是进入兔子洞的某种方式了。

  • 对于每个 ::operator new任何库引入的过载,包括来自 <new> 的新规范放置,你将不得不考虑它是否适用于你的类并决定是否添加重载,或者以其他方式应对不合格的失败 new表达式。

  • 对于每个 ::operator new你收养到你的类(class),你必须提供相应的成员安置operator delete具有正确的语义。这是在构造函数异常退出的情况下调用的。没有它只会在非常特殊的情况下,在可能资源受限的池中导致内存泄漏。

综上所述,成员(member)operator new是防御性编码的对立面。

关于c++ - 当我们重载新运算符时,是否有必要重载放置新运算符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3599956/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com