当显式调用构造函数时,是否构造了初始化程序和成员变量?

时间:2011-01-07 14:54:56

标签: c++ constructor destructor initializer placement-new

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

在这种情况下,在类的初始化部分中初始化的对象是否也能正确构造?

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

2 个答案:

答案 0 :(得分:2)

  

使用“放置新”是的   建议调用构造函数和   析构函数明确。

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

  

在这种情况下将对象   在初始化部分初始化   一个班级也得到了适当的   构造

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

  

同样明确地调用   析构函数?成员对象是否得到   被妥善摧毁了?

答案 1 :(得分:1)

  

在使用“placement 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;
}

因此,新的展示位置就像普通的新作品一样 看着删除的电话

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

这里的问题是删除无法判断内存是由new分配还是内存是由用户分配并传递给new(placement new)。所以它总是在内存上自由调用。如果您使用了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();