我看到了这样的代码:
void *NewElts = operator new(NewCapacityInBytes);
而且匹配的调用明确地使用operator delete
,稍后随之使用。
为什么要这样做而不是:
void *NewElts = new char[NewCapacityInBytes];
为什么要显式调用 operator new
和 operator delete
?
我看到了这样的代码:
void *NewElts = operator new(NewCapacityInBytes);
而且匹配的调用明确地使用operator delete
,稍后随之使用。
为什么要这样做而不是:
void *NewElts = new char[NewCapacityInBytes];
为什么要显式调用 operator new
和 operator delete
?
operator new
时,会调用全局的“原始” operator new。全局 operator new
返回一个原始的内存块,不调用对象的构造函数或任何用户定义的 new
的重载函数。因此,全局 operator new
基本上类似于 C 中的 malloc
。// Allocates space for a T, and calls T's constructor,
// or calls a user-defined overload of new.
//
T* v = new T;
// Allocates space for N instances of T, and calls T's
// constructor on each, or calls a user-defined overload
// of new[]
//
T* v = new T[N];
// Simply returns a raw byte array of `sizeof(T)` bytes.
// No constructor is invoked.
//
void* v = ::operator new(sizeof(T));
new
。根据分配模式,这可以比 new
和 delete
提供更好的性能。 - Steve Moperator new
的作用,但它并没有解释为什么我们会使用operator new(N)
而不是new char[N]
。毕竟这就是问题所在。 - Rob Kennedychar
,你正在分配一个任意大小的字节块,而不是分配一个与某个特定类型T
大小相同的块。你真的可以重载char
的operator new
吗? - Rob Kennedyoperator new
。 - sharptooth如果你写下:
T *p = new T;
这将分配足够的内存来容纳一个T,然后将T构造到其中。如果您写:
T *p = ::operator new(sizeof(T));
这将分配足够的内存来容纳一个T,但不会构造T。你可能在使用放置new的时候看到这种情况:
T *p = ::operator new(sizeof(T)); // allocate memory for a T
new (p) T; // construct a T into the allocated memory
p->~T(); // destroy the T again
::operator delete(p); // deallocate the memory
如果您使用operator new(bytesize)进行分配内存,那么您可以使用delete来释放它,而如果您通过new char[bytesize]进行分配,则必须使用delete[]进行匹配。尽可能避免使用delete[],这是一个可怕的做法。这很可能是使用operator new的根本原因。
operator new
来分配内存,就可以使用全局的operator delete
来释放内存。但是全局的operator delete
不会调用析构函数。因此,如果在调用全局的operator new
之后实际上使用placement new构造了一个对象,那么仅靠全局的operator delete
是不足以销毁该对象的。在释放内存之前,您需要显式地调用析构函数来销毁对象。本质上,全局的operator new
和operator delete
都允许您将存储分配/释放与对象初始化/销毁分离开来。 - Charles Salvia当您想要分配一块“原始”内存块并且不希望在该内存中构造任何内容时,请使用它。
分配一块原始内存块和“构造”一个字符数组之间几乎没有实际区别,但是使用operator new明确地向任何阅读代码的人传达了您的意图,这非常重要。