全局新的运算符调用语法

时间:2014-02-25 20:35:06

标签: c++ new-operator

为什么带有此签名的功能

void* operator new (std::size_t size);

不能在像这样的代码中调用

void* mem = new(100);

但是必须像这样调用

void mem = ::operator new(100);

2 个答案:

答案 0 :(得分:3)

关键字newoperator new是不同的事情。

关键字new可以:

  1. 调用operator new分配内存。它可以为分配的类型重载。传递给operator new的{​​{3}},这允许展示new和非投掷new语法,请参阅Keyword new accepts optional arguments
  2. 调用对象的构造函数。
  3. 如果构造函数抛出,则调用相应的operator delete来释放内存。请注意,如果operator delete无法访问(非公开),则new在编译时失败,因为如果构造函数抛出并且内存丢失,则无法调用operator delete
  4. 关键字new无法重载,它始终执行这些步骤。这是第1步中的operator new,可以重载,通常与第3步中的operator delete一起。

    换句话说,引擎盖下的X* p = new X(a, b, c);就像(伪代码)一样:

    X* p = static_cast<X*>(X::operator new(sizeof(X))); // 1. allocate memory
    try { 
        p->X(a, b, c); // 2. invoke the constructor
    }                              
    catch(...) { 
        X::operator delete(p); // 3. free the memory if the constructor throw
        throw; 
    }
    

    在上面,如果X没有超载其operator new,则调用全局::operator new。请注意,X::operator new如果过载则隐式静态。

答案 1 :(得分:0)

这有一个深刻的语法原因:放置新的。使用placement new,您可以调用构造函数而不为其分配内存。它的语法是:

#include <new>
Foo* foo = new(bufferPointer) Foo();

显然,部分原因是您尝试调用::operator new() ...

的准确语法