const成员、引用成员及无默认构造函数的类类型成员必须使用初始化列表;初始化顺序严格按类内声明顺序,与初始化列表书写顺序无关;初始化列表优先于类内默认值。

必须用初始化列表的成员,就只能在构造函数冒号后面写;其他成员可以选,但多数时候该用也得用。
const 成员和引用成员必须走初始化列表
它们不能“先默认构造再赋值”,因为根本没这能力。比如 const int id 或 int& ref,一旦声明就必须绑定,且不可再改。
-
id在初始化列表里写成id(val),写进函数体里id = val直接编译失败 -
ref必须绑定一个已存在的变量,ref(r)合法,ref = r不合法 - 如果引用绑定的是临时对象(比如
string("abc")),会立刻悬垂——这是常见崩溃点
没有默认构造函数的类类型成员也得靠初始化列表
假设你有个 Time 类,只提供 Time(int h) 构造函数,没写 Time()。那它作为成员时,不写初始化列表就会报错:找不到默认构造函数。
- 错误写法:
Time t;声明后没初始化 → 编译不过 - 正确写法:
Time t;+ 构造函数里写: t(12) - 哪怕这个成员是
std::vector,你也该用data{1,2,3}而不是data = {1,2,3},前者是初始化,后者是赋值(多一次默认构造+移动)
初始化顺序只看声明顺序,不看你写的顺序
哪怕你在初始化列表里把 a2 写在 a1 前面,只要类里是 int a1; int a2; 的顺序,a1 就一定先被初始化。
- 危险场景:如果
a2初始化依赖a1的值(比如a2(a1 * 2)),而a1在类里声明在a2后面,那a1还没初始化,a2就用了它的垃圾值 - 调试时很难发现,因为编译器通常不报错,只给你未定义行为
- 建议始终让初始化列表顺序和类内声明顺序一致,肉眼可查,避免隐性依赖
C++11 类内默认值和初始化列表谁优先?
初始化列表赢。它显式、直接、可控;类内默认值(如 int x = 42;)只是兜底方案。
- 写了
: x(99)→ 用 99 - 没写,但类里有
int x = 42;→ 用 42 - 都没写,且
x是内置类型 → 值未定义(栈上随机数) - 这种组合用法很实用:既提供合理默认,又允许构造时覆盖
最易被忽略的是初始化顺序和临时对象生命周期——它们不报错,但一跑就崩或结果飘忽。写初始化列表时,眼睛要盯着类定义里的成员顺序,手要避开任何对未声明成员的依赖表达式。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











