6

在挖掘 C++ 项目时,我遇到了 C++new运算符的一个奇怪用法:

int arr[5];
ClassA* a = new(arr) ClassA();

你能帮我理解这个语法吗?

4

3 回答 3

2

这是放置新语法 - 它允许您在内存中指向的位置构造一个对象。考虑 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

于 2013-11-04T11:05:54.243 回答
2

new()运算符可以采用size(以字节为单位的大小)(nothrow_value返回空指针而不是bad_alloc异常)或pointer(在此指针指向的已分配内存中构造对象)参数,并且在您描述的用法中它是创建一个新对象在 指向的内存位置arr。有关它的体面指南,我会查看此链接

在您引用的情况下,它使用 arr 的指针来创建其新的 ClassA 实例。

于 2013-11-04T11:08:26.910 回答
2

这种语法称为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自动发挥作用。您不应该取消分配正在使用内存缓冲区的每个对象。相反,您应该手动销毁每个对象,然后仅删除原始缓冲区

于 2013-11-04T11:09:43.233 回答