在挖掘C ++项目时,我遇到了C ++的new
运算符的奇怪用法:
int arr[5];
ClassA* a = new(arr) ClassA();
请您帮我理解这种语法吗?
答案 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
自动完成魔法。您不应该释放使用内存缓冲区的每个对象。相反,你应该手动破坏每个对象,然后只删除[]原始缓冲区