0

在使用“placement new”时,建议显式调用构造函数和析构函数。

在这种情况下,在类的初始化程序部分中初始化的对象也会正确构造吗?

显式调用析构函数也一样吗?成员对象是否被正确销毁?

4

2 回答 2

2

在使用“placement new”时,建议显式调用构造函数和析构函数。

说“你显式地调用构造函数”是不正确的,因为构造函数没有名称($12.1/1)。

在这种情况下,在类的初始化程序部分中初始化的对象也会正确构造吗?

是的。你为什么怀疑它?Placement new 仅表示new操作员不会分配任何内存,而是使用您在placement new 中传递的内存来构造对象。该对象在您传递的内存中构造。

显式调用析构函数也一样吗?成员对象是否被正确销毁?

是的。

于 2011-01-07T14:58:19.307 回答
1

在使用“placement new”时,建议显式调用构造函数和析构函数。

我不这么认为。它会说你需要显式调用析构函数。

在这种情况下,在类的初始化程序部分中初始化的对象也会正确构造吗?

除了提供内存之外,placement new 的所有其他方面都与普通 new 相同。因此,它不是动态分配内存,而是使用提供的指针。

显式调用析构函数也一样吗?

您可以(如果您觉得无能为力)在任何对象上显式调用析构函数。它将照常调用用户定义的(或编译器生成的)类析构函数。您需要为通过placement new 创建的对象显式执行此操作的原因是您可以对这些对象调用delete。这是因为 delete 假定对象是在动态分配的内存中创建的,并在调用析构函数后尝试重新循环该内存。

成员对象是否被正确销毁?

是的。

如果我们这样想新的:

// not real code
template<class T> T* new(void* location = NULL)  (ArgumentsForT)
{
    // If you do not provide location (normal usage)
    // then we allocate some memory for you.
    if (location == NULL)
    {    location = malloc(sizeof(T));   // Use of malloc() is just an example
    }

    ((T*)location)->Constructor(ArgumentsForT);
    return (T*)location;
}

所以放置 new 将像正常的 new 一样工作。
查看删除的调用

template<typename T> void delete(T* obj)
{
    if (obj != NULL)
    {
        obj->~T();
        free(obj);
    }
}

这里的问题是,delete 无法判断内存是由 new 分配的,还是由用户分配并传递给 new(placement new)的。所以它总是在内存上调用 free 。如果您使用placement new,那么您可能没有动态分配内存(或者内存仍在用于其他用途)。

char   x[sizeof(T)];  // don't do this (memory may not be aligned correctly).
T*  obj = new (x) T();

delete obj;  // FAIL. The memory was not dynamically allocated.
             //       Delete will try and re-claim this memory for re-yse
             //       Even if the memory is local.

 // This is why on placement new you need to call the destructor
 obj->~T();
于 2011-01-07T15:47:22.210 回答