C++中派生类构造函数必须显式调用父类构造函数,除非父类有可访问默认构造函数且派生类构造函数体为空;调用须在初始化列表开头,按继承声明顺序执行,不可在函数体内调用。

派生类构造函数必须显式调用父类构造函数
在 C++ 中,派生类构造函数不会自动调用父类构造函数(哪怕父类有默认构造函数),除非你明确写出来。编译器只会在「派生类构造函数体为空且父类有可访问的默认构造函数」时帮你隐式调用——但这属于特例,不可依赖。一旦父类没有默认构造函数,或你需要传特定参数,就必须手动调用。
-
Base()是最简形式,调用父类默认构造函数 -
Base(x, y)用于父类需要参数的情况,必须写在初始化列表里 - 不能在构造函数体内用
Base(x, y);的方式“调用”——这会被当作定义一个临时对象,毫无意义 - 若父类构造函数是
explicit的,也不能省略,否则编译失败
初始化列表中调用父类构造函数的语法位置很关键
父类构造函数调用必须出现在派生类构造函数的初始化列表开头,且位于任何成员变量初始化之前。顺序由继承声明顺序决定,不是按初始化列表书写顺序。
class Base {
public:
Base(int a) : m_a(a) {}
private:
int m_a;
};
class Derived : public Base {
public:
// ✅ 正确:Base(42) 在初始化列表最前
Derived(int x) : Base(42), m_x(x), m_y(x * 2) {}
// ❌ 错误:Base(42) 写在后面,编译器仍按 Base → m_x → m_y 顺序调用
// 但写法本身合法;真正危险的是漏掉 Base(...) 导致编译失败
private:
int m_x;
int m_y;
};
多重继承时要分别调用每个基类构造函数
如果派生类同时继承多个基类,每个基类的构造函数都必须在初始化列表中显式列出,顺序按它们在 class Derived : public A, public B 中声明的顺序执行,与初始化列表书写顺序无关。
- 遗漏任一基类构造调用,且该基类无默认构造函数 → 编译错误
- 若某基类是虚基类(
virtual public Base),它只会被最派生类初始化一次,但仍需在最派生类的初始化列表中调用 - 虚基类构造函数调用优先级最高,即使写在初始化列表末尾,也会最先执行
委托构造和父类构造调用不能共存于同一初始化列表
如果你用了委托构造(即一个构造函数调用同类另一个构造函数),就不能再在初始化列表中写父类构造调用——因为委托构造会接管整个初始化流程,包括对基类的调用。
立即学习“C++免费学习笔记(深入)”;
class Derived : public Base {
public:
Derived() : Base(100) {} // ✅ 直接调用 Base
Derived(int x) : Derived() { // ✅ 委托给无参构造
// Base(100) 已由 Derived() 完成,不能再写
}
// ❌ 错误:混合委托和 Base(...) 调用
// Derived(int x) : Derived(), Base(200) {}};
虚继承、多层继承、带 explicit 的父类构造函数,这几个点叠加时最容易出错——建议每次写派生类构造函数时,先确认父类有哪些可用构造函数,再严格按初始化列表规则排布。











