多级继承中的析构函数调用 (c++)
Call of the destructors in multilevel inheritance (c++)
我编写了以下 classes 以测试多级继承概念。在尝试测试对构造函数和析构函数的调用时,有一点我没有真正理解。
#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;
}
输出
输出如下。我了解到我们从 base class 开始。所以在 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
这与继承无关。当离开该块时,在块范围内声明的变量将被销毁,即采用 return
语句或达到最终 }
或抛出异常。
继承在这里是一个转移注意力的问题。不相关。
y
和 z
具有 自动存储持续时间 ,并且在这种情况下需要留在 范围内 [=23] =] 直到函数的右大括号。
并且z
将在之前y
被销毁。 (自动变量超出范围的顺序与它们创建的顺序相反,所有其他条件相同。)
对象存在于它们作用域的末尾,对象按照构造的相反顺序销毁。
先构造y
,再构造z
。因此,当它们的共同作用域结束时,z
首先被销毁,然后是 y
.
您期望对象按构造顺序销毁,但实际上它们以相反的构造顺序销毁。
类似地,当一个对象被构造时,它的基础class首先被构造,然后是派生的class。当对象被销毁时,派生 class 首先被销毁,然后是基础 class.
我编写了以下 classes 以测试多级继承概念。在尝试测试对构造函数和析构函数的调用时,有一点我没有真正理解。
#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;
}
输出
输出如下。我了解到我们从 base class 开始。所以在 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
这与继承无关。当离开该块时,在块范围内声明的变量将被销毁,即采用 return
语句或达到最终 }
或抛出异常。
继承在这里是一个转移注意力的问题。不相关。
y
和 z
具有 自动存储持续时间 ,并且在这种情况下需要留在 范围内 [=23] =] 直到函数的右大括号。
并且z
将在之前y
被销毁。 (自动变量超出范围的顺序与它们创建的顺序相反,所有其他条件相同。)
对象存在于它们作用域的末尾,对象按照构造的相反顺序销毁。
先构造y
,再构造z
。因此,当它们的共同作用域结束时,z
首先被销毁,然后是 y
.
您期望对象按构造顺序销毁,但实际上它们以相反的构造顺序销毁。
类似地,当一个对象被构造时,它的基础class首先被构造,然后是派生的class。当对象被销毁时,派生 class 首先被销毁,然后是基础 class.