C++中类成员初始化规则
类中成员(非静态成员)什么时候被初始化?关于初始化有哪些情况?
成员变量在类实例化时被初始化,通过构造函数来进行初始化。
关于初始化需要注意的地方有三点:
- 变量在类中有初始值
- 初始化成员列表
- 构造函数
类成员初始化的顺序如下:
- 如果类中没有定义任何的构造函数,则编译器将采用合成的默认构造来初始化类中的成员
- 如果成员在类中有初始值,则用此初始值进行初始化
- 如果没有初始值,则采用默认初始化(对于某个成员如果是类,则调用该类的默认构造函数初始化)
- 如果类中定义了构造函数,则将调用对应的构造函数进行初始化,如果该构造函数有初始化成员列表则
- 在初始化成员列表中对该成员进行初始化
- 不在初始化成员列表中的成员,先用类中初始值初始化,如果没有初始值则默认初始化
- 进入函数体后,在函数体中的成员根据函数体进行相应的赋值
注意:如果某个类有了带参的构造函数,则编译器不会为类合成默认构造函数,但是良好的编程习惯最好为每个类写出默认构造函数,防止该类对象默认初始化时保存
为什么需要初始化成员列表(C++11后可以采用类内初始值初始化)?
- 在执行构造函数体前,每个成员变量会进行默认初始化,(如果有类内初始值,则用初始值初始化)
- 如果没有初始化成员列表,则对于没有默认构造函数的类对象成员,或者常量成员,或者引用成员则无法完成初始化,从而报错
- 初始化成员列表初始化的顺序只和成员变量在类中声明的顺序有关。
从C++11开始类中各自成员所支持的初始化如下表:
type | normal | const | static | static const | 引用(包括常引用) |
---|---|---|---|---|---|
在类内声明初始化 | 是 | 是 | 否 | 否(static const int 可以) | 是 |
初始化列表初始化 | 是 | 是 | 否 | 否 | 是 |
构造函数里初始化 | 是 | 否 | 否 | 否 | 否 |
类外初始化 | 否 | 否 | 是 | 是 | 否 |
注:在C++11以前,不允许普通类型在类内声明时初始化