类中类的构造和析构顺序
思考
如下有2个类,A
和B
。我们在B
类中声明了两个A
类:_a1
和_a2
。需要思考的问题是:当我声明B
类之后,是以什么样的顺序执行构造函数和析构函数的。
class A
class A {
public:
A(int a, int b, int c) {
cout << "A(int a, int b, int c)" << endl;
}
~A(){
cout<<"~A()"<<endl;
}
private:
int _a;
int _b;
int _c;
};
class B
class B {
public :
B() : _a1(1, 2, 3), _a2(1, 4, 9) {
cout << "B()" << endl;
}
~B() {
cout << "~B()" << endl;
}
private:
A _a1;
A _a2;
};
注意:B
类中的构造函数使用了初始化成员列表。原因是在A
类中没有写无参构造函数。我们编写类时,建议要么不写任何构造函数,让编译器自动为我们生成一个构造函数;要么写构造函数,那么必须包含无参构造函数。这样做可以给一起工作的小伙伴行一个方便。当然,笔者这里的说的"必须"也不是绝对的。你的同事小伙伴也可以使用初始化成员列表绕过这种问题。这里纯纯是为了作为一个提示注意一下。
输入
int main() {
B b;
return 0;
}
输出结果
A(int a, int b, int c)
A(int a, int b, int c)
B()
~B()
~A()
~A()
当声明一个B
类后:
- 构造(construct)
- 该类先构造这个类中的成员对象,即
_a1
和_a2
(从上到下,先构造_a1
再构造_a2
)。 - 然后构造
B
类自己:这里是B()
。
- 该类先构造这个类中的成员对象,即
- 析构(destruct)
- 当全部构造完毕后,先析构
B
类自己释放堆空间。 - 然后析构
B
类中成员对象来释放对空间。(这时的析构顺序为从下到上,先析构_a2
再析构_a1
)。
- 当全部构造完毕后,先析构
总结
构造时,先构造成员对象,再构造自己本身。
析构时,先析构自己本身,再析构成员对象。