C++中构造函数和析构函数调用的次序

// constructor/destructor order

#include<fstream>
#include<iostream>
using namespace std;


#define CLASS(ID) class ID{
public:
ID(int) {cout <<#ID<<" constructor ";}
~ID() {cout <<#ID<<" destructor ";}
};

CLASS(Base1);
CLASS(Member1);
CLASS(Member2);
CLASS(Member3);
CLASS(Member4);

class Derived1 : public Base1{
Member1 m1;
Member2 m2;
public:
Derived1(int) : m2(1),m1(2),Base1(3){
cout << " Derived1 constructor ";
}
~Derived1(){
cout << " Derived1 destructor ";
}
};

class Derived2:public Derived1{
Member3 m3;
Member4 m4;
public:
Derived2() : m3(1),Derived1(2),m4(3){
cout << " Derived2 constructor ";
}
~Derived2(){
cout << " Derived2 destructor ";
}
};

int main(){
Derived2 d2;
}

可以看出,构造是从类层次的最根处开始,而在每一层,首先会调用基类构造函数, 然后调用成员对象构造函数。调用析构函数则严格按照构造函数相反的次序—这是很重要 的,因为要考虑潜在的相关性(对于派生类中的构造函数和析构函数,必须假设基类子对 象仍然可供使用,并且已经被构造了—或者还未被消除)。 另一个有趣现象是,对于成员对象,构造函数调用的次序完全不受构造函数的初始化 表达式表中的次序影响。该次序是由成员对象在类中声明的次序所决定的。如果能通过构 造函数的初始化表达式表改变构造函数调用次序,那么就会对两个不同的构造函数有两种 不同的调用顺序。而析构函数将不能知道如何相应逆序地执行析构,这就产生了相关性问 题。

原文地址:https://www.cnblogs.com/shiheyuanfang/p/14331502.html