【问题标题】:Call of the destructors in multilevel inheritance (c++)在多级继承中调用析构函数 (c++)
【发布时间】:2017-07-09 21:45:19
【问题描述】:

我编写了以下类来测试多级继承概念。当我尝试测试对构造函数和析构函数的调用时,有一点我并没有真正理解。


#include <iostream>

using namespace std;

class X{

    public:
        X(){cout <<"Construct X " << endl;};
        virtual ~X(){cout <<"Destruct X " << endl;};
        virtual void print() const = 0;
};

class Y: public X{
    public:
        Y(){cout <<"construct Y " << endl;};
        ~Y(){cout <<"Destruct Y " << endl;};
        void print() const{
            cout <<"print Y" << endl;
        };
};

class Z: public Y{
    public:
        Z(){cout <<"Construct Z" << endl; };
        ~Z(){cout <<"Destruct Z " << endl; };
        void print() const{
            cout <<" Print Z" << endl;
        };
};

int main()
{
    Y y;
    //Why isn't Y being destructed in here
    Z z;
    return 0;
}

输出

输出如下。我明白我们是从基类开始的。所以在Y y; 中,首先调用X 的构造函数,然后调用Y。在Z z; 中,首先调用X 的构造,然后调用Y,最后调用Z

Construct X
construct Y
Construct X
construct Y
Construct Z
Destruct Z
Destruct Y
Destruct X
Destruct Y
Destruct X

问题

  • 为什么没有在Y y; 之后立即调用 Y 的析构函数。为什么我们要等到 Z 构造好后再调用析构函数。意思是为什么输出看起来不像这样:

    Construct X
    construct Y
    Destruct Y
    Destruct X
    Construct X
    construct Y
    Construct Z
    Destruct Z
    Destruct Y
    Destruct X
    

【问题讨论】:

  • 这意味着yz 被构造之前被销毁。这是你所期望的吗?之后你会如何使用y
  • @HaniGotc:如果你想提前销毁一个变量,你需要将它包含在一个块中:int main() { {Y y; } Z z; }。如果 'Y' 实际上是一个获取锁的类,并且您想提前释放锁,这将很有用。

标签: c++ constructor polymorphism destructor


【解决方案1】:

继承在这里是一个红鲱鱼。不相关。

yz 具有自动存储持续时间,在这种情况下,它们必须保持在范围中,直到函数的右大括号。 p>

z 将在之前 y 被破坏。 (自动变量以它们创建的相反顺序超出范围,所有其他条件都相同。)

【讨论】:

  • (请注意,优化编译器可以破坏这条规则,只要它这样做没有副作用 - 在这种情况下会有副作用。)
  • Z 在 y 之前被销毁。因为它们被放置在堆栈上,对吗?后进先出
  • 你可以think堆栈,但我注意不要引入这个术语,因为它是一个实现概念,而不是一个语言概念(尽管有几个较新的std:: 暗指它的函数)。
  • @HaniGotc:实际上,因为可能存在依赖关系。由于 z 是在 y 之后定义的,因此 z 可以保存对 y 的引用。为了使其可靠地工作,z 的生命周期必须严格小于 y 的生命周期。
【解决方案2】:

这与继承无关。当离开该块时,在块范围内声明的变量将被销毁,即采用 return 语句或到达最终的 } 或引发异常。

【讨论】:

    【解决方案3】:

    对象存在于其作用域的末尾,并且对象以其构造的相反顺序被销毁。

    首先构造y,然后构造z。因此,当它们的相互作用域到达终点时,z 首先被销毁,然后是 y

    您期望对象按照它们被构造的顺序被销毁,但它们实际上以相反的构造顺序被销毁。

    类似地,当一个对象被构造时,它的基类首先被构造,然后是派生类。当对象被销毁时,派生类首先被销毁,然后是基类。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-04
      • 1970-01-01
      • 2016-10-09
      • 1970-01-01
      • 2012-04-28
      • 2021-04-13
      • 2012-06-18
      • 2019-01-15
      相关资源
      最近更新 更多