【问题标题】:unable to understand the destructor call sequence无法理解析构函数调用顺序
【发布时间】:2014-10-08 22:18:15
【问题描述】:
class base{
    public:
        ~base(){
             cout<<"base class delete"<<endl;
        }   
};

class derived:public base{
    public:
        ~derived(){
            cout<<"derived class 1 delete"<<endl; 
        }
};

class derived2:public base,public derived{
    public:
        ~derived2(){
            cout<<"derived class 2 delete"<<endl;
        }
};

int main(){
    derived2 h; 
    return 0;
}

产生的输出是:

派生类 2 删除
派生类 1 删除
基类删除
基类删除

我知道析构函数的调用顺序与构造函数相反,但我无法理解这个输出。谁能解释一下这种行为?

【问题讨论】:

  • 你到底有什么不明白的?你觉得这个输出有什么奇怪的地方?是什么引发了这个问题?

标签: c++ inheritance destructor


【解决方案1】:

以相反的声明顺序调用析构函数。所以一旦derived2的析构函数被调用,然后derived的dtor被调用,而不是base的。因此,基类的第三个输出由derived 类调用。一旦完成,从derived2 继承的一个类是base,所以第四个输出来自derived2 类。

总结一下:

  1. 第一个输出来自derived2 类
  2. 第二个输出来自被派生类继承的派生类
  3. 第三个输出来自派生类继承的基类
  4. 第四个输出来自派生类继承的基类

【讨论】:

    【解决方案2】:

    1) 析构函数按照从派生到基数的相反顺序调用。

    2)每个非虚基类的销毁都是按照它们声明的相反顺序进行的

    所以在你的情况下:

    我们从derived2开始,去它最后声明的基地(derived)摧毁它(摧毁derived然后base)然后回来摧毁另一个基地,即base .

    另请参阅this FAQ entry 了解更多详细信息以及虚拟基地的一般情况。

    【讨论】:

      【解决方案3】:

      你看到这个破坏顺序了吗:

      derived 2 ==> derived 1 && base ==> base
      

      解释:

      • (a) 调用 Derived 2 的析构函数
      • (b)cout&lt;&lt;"derived class 2 delete"&lt;&lt;endl; 从 (a) 调用
      • (c) 调用 Derived 1 的析构函数。
      • (d)cout&lt;&lt;"derived class 1 delete"&lt;&lt;endl; 从 (c) 调用
      • (e) 从 (c) 调用基类的析构函数
      • (f) 基类的析构函数来自 (a)

      【讨论】:

        【解决方案4】:

        析构函数的执行顺序与构造函数相反。

        • 这里,销毁从“类派生 2”开始(因此,首先调用其析构函数)。

        • 然后通过调用其析构函数来销毁最后一个继承的类(即派生类):~derived(){}。它继承了一个类,即“类基”,因此它的析构函数称为:~base(){}。

        • 最后,“类派生 2”继承的第一个类通过调用其析构函数被销毁(即类基类):~base(){}

        【讨论】:

        • 这个答案是否包含之前的答案中未提及的内容?
        猜你喜欢
        • 2018-05-08
        • 2013-06-24
        • 2023-03-31
        • 2012-05-22
        • 1970-01-01
        • 2011-01-16
        • 2011-11-24
        • 2013-04-14
        相关资源
        最近更新 更多