理解 C++ new 运算符

Understanding c++ new operator

假设 ITEM 是 class

ITEM* items = new ITEM[10];
for(i=0;i<10;++i)
    new(&items[i)ITEM();
new(&items[0])ITEM(items[1]);

以上是否有效?

我的理解是new运算符的最后2次使用 不分配内存。他们只是调用 ITEM 的构造函数。

上面是否等同于?

ITEM* items = new ITEM[10];
for(i=0;i<10;++i)
    items[i] = ITEM();
item[0] = ITEM(items[1]);

编辑:

https://github.com/gosom/practice-cpp/blob/master/arrays/darray.h

我在这里使用它(练习)

for(i=0;i<10;++i)
    new(&items[i)ITEM();

以上可能无效。 new 运算符已经构造了数组中的每个对象。这是双重构造(对于不重要的类型,它可能而且很可能会导致错误)。

for(i=0;i<10;++i)
    items[i] = ITEM();

这只是为数组中的每个条目分配一个默认构造的对象。这和赋值运算符一样安全。

一般放置 new 应该用于 raw 内存。

The way I understand it is that the last 2 uses of the new operator do not allocate memory. They just invoke the constructor of ITEM.

是的。这是 "placement new" 运算符,它不分配内存并调用对象构造函数。按照你的方式进行是合法的,尽管 ITEM 构造函数将被调用两次(这意味着 ITEM class 构造函数将被执行两次:标准 new 是调用,一个在放置 new 被调用时)。如果在 ITEM 的构造函数中分配了一些资源,这可能会导致内存泄漏(或其他意外行为)。有关新展示位置的更多信息,请参阅 this

Is the above equivalent to?

不,这不等价。在后一种情况下,您在每个循环中创建一个临时对象,并将其复制到 item[i]。这将在每个循环中调用 ITEM 构造函数、赋值运算符和析构函数。之前的情况placement new只调用了ITEM构造函数,没有别的。

"placement new" 的典型用法是当您希望将对象分配到特定的内存区域时(而不是标准 new 运算符分配内存的堆)。这可能是共享内存等等... "Placement new" 是明确调用对象析构函数 can/must 的少数情况之一,即:item[i]->~ITEM()