在挖掘 C++ 项目时,我遇到了 C++new
运算符的一个奇怪用法:
int arr[5];
ClassA* a = new(arr) ClassA();
你能帮我理解这个语法吗?
在挖掘 C++ 项目时,我遇到了 C++new
运算符的一个奇怪用法:
int arr[5];
ClassA* a = new(arr) ClassA();
你能帮我理解这个语法吗?
这是放置新语法 - 它允许您在内存中指向的位置构造一个对象。考虑 new 的“正常”使用:
X *p = new X;
...
delete p;
您可以通过执行以下操作来达到相同的效果:
#include <new>
...
void *buffer = ::operator new(sizeof(X));
X *p = new (buffer) X;
...
p->~X();
::operator delete(buffer);
后者分配足够的内存来保存一个X
(而不X
在其中构造一个),然后X
在分配的内存中显式构造一个。后来,它显式地破坏了X
它创建的内存,然后释放了包含它的内存。
另请参阅 C++ 常见问题解答:http: //www.parashift.com/c++-faq/placement-new.html
new()
运算符可以采用size
(以字节为单位的大小)(nothrow_value
返回空指针而不是bad_alloc
异常)或pointer
(在此指针指向的已分配内存中构造对象)参数,并且在您描述的用法中它是创建一个新对象在 指向的内存位置arr
。有关它的体面指南,我会查看此链接。
在您引用的情况下,它使用 arr 的指针来创建其新的 ClassA 实例。
这种语法称为placement new
语法。它通常用于在预分配的缓冲区上构造对象。这在构建内存池、垃圾收集器或仅在性能和异常安全至关重要时非常有用(由于内存已经分配,因此没有分配失败的危险,并且在预分配的缓冲区上构建对象需要更少的时间) .
char *buf = new char[sizeof(string)]; // pre-allocated buffer
string *s1 = new (buf) string("test1"); // placement new
string *s2 = new string("test2"); //ordinary new
在解除分配方面,没有什么能placement delete
自动发挥作用。您不应该取消分配正在使用内存缓冲区的每个对象。相反,您应该手动销毁每个对象,然后仅删除原始缓冲区