【问题标题】:Strange C++ new operator usage [duplicate]奇怪的 C++ 新运算符用法 [重复]
【发布时间】:2013-11-14 23:43:50
【问题描述】:

在挖一个C++项目的时候,遇到了一个C++的new操作符的奇怪用法:

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

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

【问题讨论】:

标签: c++ new-operator


【解决方案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 实例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-10
      • 2021-07-23
      • 2021-05-11
      • 2011-10-21
      • 2014-02-02
      相关资源
      最近更新 更多