奇怪的C ++新运算符用法

时间:2013-11-04 11:00:44

标签: c++ new-operator

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

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

请您帮我理解这种语法吗?

3 个答案:

答案 0 :(得分: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 ++ FAQ:http://www.parashift.com/c++-faq/placement-new.html

答案 1 :(得分:2)

new()运算符可以采用size(字节大小)nothrow_value(返回空指针而不是bad_alloc例外)或pointer(在此指针所指向的已分配内存中构造对象,并在您描述的用法中,它在arr指向的内存位置创建一个新对象。对于一个体面的指南,我会看this link

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

答案 2 :(得分: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自动完成魔法。您不应该释放使用内存缓冲区的每个对象。相反,你应该手动破坏每个对象,然后只删除[]原始缓冲区