奇怪的 C++ 新运算符用法 [重复]
Posted
技术标签:
【中文标题】奇怪的 C++ 新运算符用法 [重复]【英文标题】:Strange C++ new operator usage [duplicate] 【发布时间】:2013-11-14 23:43:50 【问题描述】:在挖一个C++项目的时候,遇到了一个C++的new
操作符的奇怪用法:
int arr[5];
ClassA* a = new(arr) ClassA();
你能帮我理解这个语法吗?
【问题讨论】:
google "placement new" 或者看到这个问题:***.com/questions/222557/… @Askyane 我已经包含了一个简短的摘要和一个链接供您阅读 【参考方案1】:这是放置新语法 - 它允许您在内存中指向的位置构造一个对象。考虑“正常”使用 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
【讨论】:
【参考方案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
可以自动发挥作用。您不应该取消分配正在使用内存缓冲区的每个对象。相反,您应该手动销毁每个对象,然后仅删除 [] 原始缓冲区
【讨论】:
我认为您的意思是手动销毁每个对象,然后删除原始缓冲区,而不是反过来。 @StuartGolodetz 为那个愚蠢的错误感到抱歉。改正了【参考方案3】:new()
运算符可以采用size
(以字节为单位)nothrow_value
(返回空指针而不是bad_alloc
异常)或pointer
(在指向的已分配内存中构造对象通过此指针)参数,并且在您描述的用法中,它是在arr
指向的内存位置创建一个新对象。对于它的体面指南,我会看this link。
在您引用的情况下,它使用 arr 的指针来创建其新的 ClassA 实例。
【讨论】:
以上是关于奇怪的 C++ 新运算符用法 [重复]的主要内容,如果未能解决你的问题,请参考以下文章