使用初始化列表的情况
- 成员变量是const类型
- 成员变量是引用类型
- 成员变量的自定义类型(且该类型构造函数是非默认构造)
初始化与赋值的区别
初始化:对一个不存在的变量进行定义并赋值int a=10;
赋值:对一个已经存在变量进行赋值int a; a=10;
构造函数体内部是赋值
定义一个const常量,该类型需要在定义时初始化,如果不初始化就会报错
所以类内定义的const成员变量也需要初始化,当在构造函数的函数体中初始化_a,运行后报错;
- 说明构造函数体内部是赋值,并不是对成员变量初始化
- 要对成员变量进行真正的初始化就需要用到初始化列表,
- 除了拷贝构造函数(拷贝构造也是构造的一种),其它成员函数都没有初始化列表。
初始化列表
每个成员变量在初始化列表处只能出现一次
- 初始化列表可以认为是 对象成员变量定义的地方
- 用户不定义编译器会自动生成
- 成员变量在类中声明次序 是其在初始化列表中的初始化顺序(谁先声明先在列表处初始化谁)
与其在初始化列表中的先后次序无关
例:a2的值就是随机值
const成员变量初始化:
const不能修饰构造函数,拷贝构造函数,析构函数,运算符重载;
因为它们函数本身就要对成员变量进行操作
也可以直接在90行对const成员赋值,这样自动生成的初始化列表就会使用该默认值作为常量的初始值
自定义类型成员初始化
初始化_t就必须在Date类对象的构造函数的初始化列表处调用Time类构造函数初始化_t,
如果是默认的,则编译通过(因为调用不需要传参);
调用Time类构造函数则需要在Date类构造函数的初始化列表调用
整个代码执行顺序如上标号
- 先初始化对象d
- d内部 有自定义Time类型对象_t,所以也需将_t初始化,
但是在定义对象传参的时候并没有时间类的参数;
-
如果用户定义的Time类构造函数不是默认的,
且还不加_t(1,1,1)
语句,编译器就不知道如何调用Time类构造初始化对象剩余的参数
-
_t(1,1,1)
语句就是为了调用Time类的非默认构造函数,初始化_t对象
成员变量的缺省值
是给初始化列表使用的
赋值优先级:
初始化列表值>参数缺省值?成员变量缺省值(这俩要分情况,day就是先用参数值,自动生成的month就是用成员变量值)
临时变量
总结
-
类中的成员是自定义类型,则初始化自定义类型的成员时,是在类中的初始化列表调用自定义类型的构造函数
-
编译器自动生成的初始化列表会使用成员变量的缺省值
所以说自动生成的初始化列表都是_year(6),括号里是带默认值的
-
_year(year)这样子是指定使用形参列表的缺省值