【问题标题】:What are "::operator new" and "::operator delete"?什么是“::operator new”和“::operator delete”?
【发布时间】:2012-05-09 09:35:04
【问题描述】:

我知道newdelete 是关键字。

int obj = new int;
delete obj;

int* arr = new int[1024];
delete[] arr;

<new> 标头是 C++ 标准标头的一部分。它有两个运算符(我不确定它们是运算符还是函数):

::operator new

::operator delete

这些运算符的用法如下:

#include <new>
using namespace std;

int* buff = (int*)::operator new(1024 * sizeof(int));
::operator delete(buff);

什么是“::operator new”和“::operator delete”?它们与newdelete 关键字有什么不同吗?

【问题讨论】:

    标签: c++ new-operator operator-keyword delete-operator


    【解决方案1】:

    new 关键字(单独使用)与operator new 函数不同。

    打电话

    Object* p = new Object(value);
    

    在调用中是等价的

    void* v = operator new(sizeof(Object));
    p = reinterpret_cast<Object*>(v);
    p->Object::Object(value); //this is not legal C++, it just represent the implementation effect
    

    操作符 new(或更好的 void* operator new(size_t) 变体)只是分配内存,但不进行任何对象构造。

    new 关键字调用 operator new 函数,然后调用对象构造函数。

    为了将分配与构造分开,运算符 new 的变体被声明为

    void* operator new(size_t, void* at)
    { return at; }
    

    而前面的代码通常写成

    Object* p = reinterpret_cast<Object*>(operator new(sizeof(Object))); //no contruction here
    new(p) Object(value); //calls operator new(size_t, void*) via keyword
    

    operator new(size_t, void*) 本身什么都不做,但是,被关键字调用会导致构造函数被调用。

    反过来,销毁和释放可以用

    分开
    p->~Object();
    operator delete(p); //no destructor called
    

    而不是delete p;调用析构函数,然后调用operator delete(void*)

    【讨论】:

      【解决方案2】:

      :: 告诉编译器调用全局命名空间中定义的运算符。
      它是全局 newdelete 运算符的完全限定名称。

      请注意,可以replace the global new and delete operators as well as overload class-specific new and delete operators。所以一个程序中可以有两个版本的newdelete运算符。具有范围解析运算符的完全限定名称告诉编译器您指的是运算符的全局版本,而不是特定于类的运算符。

      【讨论】:

      • 但是程序员应该包含new header。
      • @AmirSaniyan 如果您希望使用placement new,则包含新标题的唯一原因(我知道)
      • @Als 正如 Benj 所说:如果您使用的是新的标准展示位置之一。或者,如果您需要访问std::bad_alloc,或在标头中声明的少数其他函数之一。标准的非放置 new 不需要它,不管你是只写new MyType 还是::new MyType,如果你是new 表达式解析为用户定义的operator new,而不是一个 in标准库。
      • @JamesKanze:是的,所以我将相关的 Q 链接为评论,那里的答案之一(不是接受的答案)恰当地清除了这一点。
      【解决方案3】:

      它们是分配器和释放器函数。 new 运算符确实 两件事:它调用一个分配器函数来获取内存,它 调用对象的构造函数。 delete 运算符也可以 两件事:它调用析构函数,然后调用释放器 功能。默认分配器函数是::operator new,并且 默认释放函数是::operator delete。两者都可以 由用户替换。

      请注意,在新表达式中,::operator new 函数被查找 以或多或少与正常情况下相同的方式上升 从成员函数中调用的函数。至于正常功能, 您可以限定操作员以更改查找:new MyClass 将 找到成员operator new(如果有的话); ::new MyClass 将使用 默认分配器,即使 MyClass 定义了成员 operator new

      【讨论】:

      • +1 用于区分分配函数和 new-expression。两者都在语法中使用 new 关键字。
      【解决方案4】:

      :: 只是一个全局命名空间

      【讨论】:

      • new是关键字时,为什么要使用全局命名空间?
      • 您不应该表明您正在使用全局命名空间中的新内容。但是您可以覆盖您的新版本,然后如果需要,您将使用您的命名空间
      猜你喜欢
      • 2011-08-30
      • 2012-01-03
      • 2021-07-28
      • 1970-01-01
      • 1970-01-01
      • 2019-02-25
      • 2017-01-31
      • 2014-01-23
      • 2022-11-20
      相关资源
      最近更新 更多