8

我知道new并且delete是关键字。

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关键字不同吗?

4

4 回答 4

14

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*).

于 2012-05-09T10:31:25.270 回答
11

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

请注意,可以替换全局newdelete运算符以及重载类特定的newdelete运算符。所以一个程序中可以有两个版本的newanddelete运算符。具有范围解析运算符的完全限定名称告诉编译器您指的是运算符的全局版本,而不是特定于类的运算符。

于 2012-05-09T09:36:25.993 回答
4

它们是分配器和释放器函数。操作符做了new两件事:它调用分配器函数来获取内存,它调用对象的构造函数。操作符还做了delete两件事:它调用析构函数,然后调用一个释放函数。默认分配器函数是::operator new,默认释放器函数是::operator delete。两者都可以由用户更换。

请注意,在新表达式中,::operator new函数的查找方式与从成员函数中调用普通函数的方式大致相同。对于普通函数,您可以限定操作符以更改查找:如果成员存在,new MyClass将查找成员;将使用默认分配器,即使定义了一个成员。operator new::new MyClassMyClassoperator new

于 2012-05-09T09:57:27.170 回答
3

::意味着只是一个全局命名空间

于 2012-05-09T09:37:09.180 回答