代码之家  ›  专栏  ›  技术社区  ›  Roger Pate

C++ 0x仍然显式地用全局运算符新分配吗?

  •  17
  • Roger Pate  · 技术社区  · 14 年前

    Wikipedia

    struct NonNewable {
        void *operator new(std::size_t) = delete;
    };
    

    此类型的对象只能作为堆栈对象或其他类型的成员进行分配。如果没有不可移植的技巧,它就不能直接堆分配。(由于placement new是在用户分配的内存上调用构造函数的唯一方法,并且如上所述禁止这种使用,因此无法正确构造对象。)

    删除运算符new类似于在当前C++中使其私有,但不明确地使用全局运算符new,从而避免了类特定查找,仍然有效C++ +0x?

    NonNewable *p = ::new NonNewable();
    // neither non-portable nor trickery, though perhaps not widely known
    


    works fine :

    struct NonNewable {
    private:
      void *operator new(std::size_t);  // not defined
    };
    
    int main() {
      // ignore the leaks, it's just an example
    
      void *mem = operator new(sizeof(NonNewable));
      NonNewable *p = ::new(mem) NonNewable();
    
      p = ::new NonNewable();
    
      return 0;
    }
    
    1 回复  |  直到 14 年前
        1
  •  7
  •   Community CDub    4 年前

    我相信你是对的,维基百科是错的。C++ 0x草案标准将“删除函数”(84P10)描述为不可用于任何方式的函数(或程序不正确的形成)。它们在作用域或名称查找中的作用与普通函数不同。关于新词语的相关段落保持不变:

    [5.3.4p8]一个新的表达式通过调用一个分配函数(3.7.4.1)来获得对象的存储。。。

    [5.3.4p9]如果新表达式以一元::运算符开头,则在全局范围中查找分配函数的名称。否则,如果分配的类型是类类型T或其数组,则在T的作用域中查找分配函数的名称。如果此查找找不到名称,或者如果分配的类型不是类类型,则在全局作用域中查找分配函数的名称。

    是的,这个表达 ::new NonNewable [或 ::new(mem) NonNewable ]会选择超负荷的 ::operator new ,忽略函数 NonNewable::operator new