构造函数执行顺序决定父子类字段初始化先后:基类字段先于派生类字段初始化;多继承按声明顺序初始化基类;虚基类优先且仅初始化一次;成员变量初始化严格按类内声明顺序,与初始化列表顺序无关。

构造函数执行顺序直接决定了父子类字段初始化的先后逻辑。理解这个顺序,就能预判每个字段何时被赋值、是否依赖其他字段、会不会出现未初始化访问等问题。
基类字段先于派生类字段初始化
在单继承或多继承中,所有基类的构造函数一定在派生类构造函数体执行前完成。这意味着:
- 基类中定义的成员变量(包括私有字段)会在派生类字段之前完成构造和初始化
- 即使派生类字段在代码中声明得更早,它也必须等所有基类构造完毕才开始初始化
- 若基类构造函数中调用了虚函数,且该函数在派生类中被重写,此时调用的是派生类版本——但派生类字段尚未初始化,可能引发未定义行为
多继承时按声明顺序逐个初始化基类
当一个类继承多个基类(如 class D : public A, public B, public C),字段初始化严格遵循声明顺序:
- A 的全部字段(含其基类字段)最先初始化
- 然后是 B 的全部字段(注意:B 自身可能还有继承关系,会递归展开)
- 最后是 C 的全部字段
- D 自身声明的字段,在所有基类构造完成后、D 构造函数体执行前,按声明顺序依次初始化
虚继承改变虚基类的初始化时机
虚基类的字段初始化优先级最高,但由最派生类直接负责:
- 虚基类构造函数总是在所有非虚基类之前调用
- 即使虚基类出现在继承列表靠后位置(如 class D : public A, virtual public V),V 仍先于 A 构造
- 若多个类都虚继承自同一个类(如 A 和 B 都 virtual public V),V 只构造一次,且由最终派生类 D 直接调用,避免重复初始化
- V 中的字段因此成为整个继承链中最先就位的数据,可被后续所有基类构造函数安全使用
成员变量初始化顺序独立于构造函数参数列表
派生类构造函数初始化列表的书写顺序不影响实际执行顺序:
- 初始化列表里写成 A(), B(), m_x(1), m_y(2),但只要类声明是 class D : public B, public A,实际仍是先 B 后 A
- 成员变量初始化始终按它们在类体内声明的顺序,与初始化列表顺序无关
- 若成员变量间存在依赖(如 m_y 初始化依赖 m_x 已构造),就必须确保 m_x 在 m_y 之前声明,否则即使列表里先写 m_y,也会出错

















