我编写了以下类来测试多级继承概念。当我试图测试对构造函数和析构函数的调用时,有一点我真的不明白。
#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;
中,首先调用 的构造函数,然后 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
答案 0 :(得分:8)
继承在这里是一个红鲱鱼。这没关系。
y
和z
自动存储时间,在这种情况下,必须保留在范围中,直到功能
z
将在 y
之前被破坏。 (自动变量按照创建它们的相反顺序超出范围,所有其他条件相同。)
答案 1 :(得分:4)
这与继承无关。在块范围内声明的变量在该块被删除时被销毁,即采用return
语句或达到最终}
或抛出异常。
答案 2 :(得分:0)
对象存在于其范围的末尾,对象以其构造的相反顺序被销毁。
首先构建 y
,然后z
。因此,当达到他们的共同范围时,z
首先被销毁,然后y
。
你期望对象以它们构造的相同顺序被销毁,但它们实际上会以相反的构造顺序被销毁。
类似地,当构造一个对象时,首先构造它的基类,然后构造派生类。当对象被销毁时,派生类首先被销毁,然后是基类。