首先上一段代码:
//Order.cpp
//构造函数和析构函数的调用顺序
#include
using namespace std;
ofstream out("order.out"); //输出到文件
//宏定义
#define CLASS(ID) class ID { \
public: \
ID(int) {
out << #ID " constructor\n";
} \
~ID() { out
<< #ID " destructor\n"; }
\ };
//定义五个class
CLASS(Base1);
CLASS(Member1);
CLASS(Member2);
CLASS(Member3);
CLASS(Member4);
//定义class Derived1
class Derived1 : public Base1 {
Member1 m1;
Member2 m2;
public: Derived1(int) :
m2(1),m1(2),Base1(3) { out<
constructor\n"; }
~Derived1() {
out<
};
//定义class Derived2
class Derived2 : public Derived1 {
Member3 m3;
Member4 m4;
public: Derived2() :
m3(1),m4(3),Derived1(2)
{out<
constructor\n";}
~Derived2()
{out<
};
//程序入口
int main() {
Derived2 d2; //构造Derived2
return 0;
}
以下是注释,说明了构造函数的调用顺序
///
//构造函数调用顺序:
//1.构造Derived2时,首先构造基类Derived1
//2.构造Derived1时,首先构造基类Base1
//3.构造Base1后,构造Derived1中的成员对象Member1和Member2(依照声明顺序构造)
//4.构造Derived1
//5.构造Derived2中的成员对象Member3和Member4(依照声明顺序构造)
//6.构造Derived2///
//
//析构函数调用顺序按照栈的原则,后进先出,因此调用顺序与构造顺序完全相反
//输出到文件order.out中的字符串如下:
//
总体来说,结合了组合和继承的c++类中,构造函数和析构函数的调用顺序具有以下规律:
1、对于继承:如果有基类,首先构造指定类的基类;
2、对于组合:按照嵌入的成员对象的声明顺序构造它们,成员对象构造完成后再构造封装它们的这个类;
3、构造和析构本身依赖于压栈和出栈,因此析构函数的函数的调用应该遵循栈的特性,以“后进先出”为原则——析构函数的调用与构造函数完全相反,先构造的后析构,后构造的先析构;
4、详情参考上述注释,如有疑问欢迎留言讨论或者自己粘贴代码编译运行。
PS:html里代码不方便编辑颜色,用html和css来写blog也是蛋疼...所以对代码颜色有要求的朋友请自己用IDE看
参考文献:
1.
C++> author: Bruce Eckel
2.
Model> author: Stanley B.Lippman