显式调用析构函数的行为

时间:2013-03-12 17:58:16

标签: c++ destruction

some_class的定义是:

class some_class
{
   // stuff

public:
   ~some_class()
   {
         delete dynamic_three;
   }

private:
   classA one;
   classB two;
   classC* dynamic_three;
}

当一个对象的生命周期结束时,它的破坏是:(1)调用它的析构函数和(2)以类定义(=内存中的位置)声明它们的相同顺序销毁它的子对象。

但是,如果我有类似的东西:

auto* ptr = new some_class();

// more stuff

ptr->~some_class(); // l. X

步骤(2)也实现了吗?我的意思是,在第X行中,子对象的析构函数也被调用或仅被执行some_class的析构函数的主体?

3 个答案:

答案 0 :(得分:2)

  

步骤(2)也实现了吗?

是的,这是有保障的。行为是安全的,但请注意,在您的情况下,您无法安全地回收对象的内存,而无需先通过placement-new重新构建它(除非您为对象重叠operator new,因此您可以保证如何分配内存并使用匹配的释放)。

答案 1 :(得分:2)

让我们做一个测试:

class classA
{
public:
    ~classA() { cout << "~classA()" << endl; }
};

class classB
{
public:
    ~classB() { cout << "~classB()" << endl; }
};

class some_class
{
public:
    ~some_class() { cout << "~some_class()" << endl; }

private:
    classA one;
    classB two;
};

int main()
{
    cout << "Start..." << endl;

    auto* ptr = new some_class();

    ptr->~some_class();

    cout << "End." << endl;
}

输出:

  

...开始

     

〜some_class()

     

〜CLASSB()

     

〜CLASSA()

     

结束。

所以所有析构函数都以相反的顺序被调用。

答案 2 :(得分:1)

  

当一个对象的生命周期结束时,它的破坏是:(1)调用它的析构函数和(2)以类定义(=内存中的位置)声明它们的相同顺序销毁它的子对象。

和(3)释放分配的内存。

  

步骤(2)也实现了吗?

步骤(2)是,但不是步骤(3)。

但如果你能写

auto* ptr = new some_class();

请注意,您也可以写

std::unique_ptr<ptr> ptr (new some_class());

会为你调用delete(当然,只有在满足你的需要时才使用它,但如果你不确定则默认使用它。)