C++类对象的构造(初始化)和析构(反初始化)的顺序
C++对象的内存分配是一次性完成的,类对象在分配内存时会一次性分配整个对象的内存空间。然后再逐步进行类的初始化。
一、构造(初始化)顺序
C++对象的构造顺序是:
- 基类对象
- 成员对象
- 对象自身
这种构造顺序的考虑是多方面的,,主要有以下几种考虑。
1,考虑到资源的依赖关系。被别的资源依赖的对象总是要最先构造而最后析构的。因为它要在别的资源构造之前就被构造,保证别的资源构造时能够访问到它。它也要在别的资源被析构后才能被析构,保证别的资源在析构时也能够访问到它。栈中对象的生命周期的管理,也是先进后出,也是基于这样的考虑。
构建C++类对象时,先构造底层的依赖,再构造上层的对象。因为上层的对象在构造函数中,可能使用到底层的依赖对象,此时如果底层依赖对象还未初始化,会导致的未定义的行为。
C++成员对象可能会依赖基类对象的资源(构造时,需要使用基类对象的数据或虚函数来作为构造参数),C++对象依赖基类对象和成员对象的资源,所以,先构造基类对象,再成员对象,再对象自身。
2,在内存布局上,也是先是排布基类对象,再成员对象,从而构成整个派生类对象。
3,在概念上,应该先建立IS-A关系,再建立HAS-A关系。从面向对象的角度,基类代表了对象的“本质”,而成员对象是“组成部分”。先有本质,再有组成,也是一种逻辑顺序。
多重继承时,基类的构造顺序是按照继承顺序来的。
成员对象构造或初始化顺序,也是按照它们在类内的声明的顺序来的。
二,析构(反初始化)顺序
析构的顺序与构造的顺序必然是相反的,这样才能保证在析构函数中,每个成员变量、基类对象仍然可以被安全地访问。
所以,先析构最上层,再析构下层的依赖。避免因为下层依赖被析构后,上层的析构函数使用了下层的依赖,导致的未定义行为。析构的顺序为:
- 对象自身
- 成员对象
- 基类对象
三,对象的构造过程
当一个对象被创建时,会先分配内存,再进行初始化/构造:
1. 分配内存:一次性分配整个对象的内存空间,包括所有基类子对象和成员对象的内存。内存布局和大小在编译时确定。
2. 构造基类子对象:按照继承顺序,在对象内存的对应偏移位置构造基类对象,调用基类的构造函数。
3. 构造/初始化成员对象:按照声明顺序,在对象内存的对应偏移位置构造成员对象,调用成员对象的构造函数。
4. 执行派生类构造函数体:调用派生类自己的构造函数,执行构造函数体内的代码。
class MyClass
{
public:
// 初始化a时,使用到b。此时能够访问到b的内存,因为此时内存已经分配。、
// 但是b还没有初始化,访问到的b内存中的未初始化的数据,
// 比如a可能被初始化为-858993460
int a = b;
int b = 12;
};
更多推荐



所有评论(0)