C++学习笔记之初始化列表
创建一个类对象时编译器通过调用构造函数给类对象中各个成员变量赋初值12345678910111213141516classDate{public://构造函数Date(intyear 2022,intmonth 4,intday 19){_year year;_month month;_day day;}private:int_year;int_month;int_day;};但上述赋初值不能称作类对象成员的初始化因为构造函数体内可以多次赋值1234567891011121314151617classDate{public://构造函数Date(intyear 2022,intmonth 4,intday 19){_year year;_month month;_day day;_year 2023;//构造函数体内允许对成员变量进行多次赋值}private:int_year;int_month;int_day;};而初始化列表能只能初始化一次。一、用初始化列表初始化对象1.初始化列表用法初始化列表以一个冒号开始接着是一个以逗号分隔的数据成员列表每个成员变量后面跟一个放在括 号中的初始值或表达式。123456789101112131415classDate{public://构造函数Date(intyear 2022,intmonth 4,intday 19):_year(year)//初始化列表初始化,_month(month),_day(day){}private:int_year;int_month;int_day;};2.初始化列表特性1初始化列表能只能初始化一次多次初始化会报错12345678910111213141516classDate{public://构造函数Date(intyear 2022,intmonth 4,intday 19):_year(year),_month(month),_day(day),_month(month)//初始化列表多次初始化{}private:int_year;int_month;int_day;};编译器也允许构造函数赋初值和初始化列表初始化混用12345678910111213141516classDate{public://构造函数Date(intyear 2022,intmonth 4,intday 19):_year(year)//两者混用,_month(month){_day day;}private:int_year;int_month;int_day;};混用时初始化列表初始化和构造函数赋初值不冲突1234567891011121314151617classDate{public://构造函数Date(intyear 2022,intmonth 4,intday 19): _year(year)//两者不冲突, _month(month){_day day;_year 2023;}private:int_year;int_month;int_day;};但混用时初始化列表初始化还是要遵循只能初始化一次成员变量的原则1234567891011121314151617classDate{public://构造函数Date(intyear 2022,intmonth 4,intday 19): _year(year)//初始化列表初始化, _month(month), _year(2023)//_year在初始化列表里被初始化了两次不允许{_day day;}private:int_year;int_month;int_day;};2const成员变量、引用成员变量、没有默认构造函数的自定义类型成员只能在初始化列表初始化。①const成员变量必须在定义的时候初始化1234567891011121314151617181920classDate{public://构造函数Date(intyear 2022,intmonth 4,intday 19): _year(year), _month(month), _n(2)//const成员变量必须使用初始化列表进行初始化{_day day;//_n 2; //const成员变量不能在函数体内初始化}private:int_year;int_month;int_day;constint_n 1;};②引用成员变量必须在定义的时候初始化1234567891011121314151617181920classDate{public://构造函数Date(intyear 2022,intmonth 4,intday 19): _year(year), _month(month),_ref(year)//引用成员变量要在初始化列表初始化{_day day;//_ref year; //引用成员变量不能在函数体内初始化}private:int_year;int_month;int_day;int _ref;};③没有默认构造函数的自定义类型成员变量1234567891011121314151617181920212223242526272829303132333435363738394041#include iostreamusingnamespacestd;classA{public://默认构造函数是不用传参就可以调用的构造函数有3种//1.无参默认构造函数//2.带参全缺省的默认构造函数//3.我们不写编译器自动生成的默认构造函数A(intx)//不属于以上任何一种所以A类的对象没有默认构造函数{cout A(int x) endl;_x x;}private:int_x;};classDate{public://构造函数Date(intyear 2022,intmonth 4,intday 19): _year(year), _month(month), _a(20)//没有默认构造函数的自定义类型成员变量必须在初始化列表进行初始化{_day day;}private:int_year;int_month;int_day;A _a;};const成员变量、引用成员变量、没有默认构造函数的自定义类型成员变量必须在初始化列表内初始化的原因①初始化列表是对象的成员变量定义的地方。②对象的内置类型成员变量在初始化列表定义时没有要求必须初始化因此既可以在初始化列表进行初始化也可以在构造函数体内初始化。③而const成员变量、引用成员变量、没有默认构造函数的自定义类型成员变量不能先定义再初始化它们在初始化列表内定义并且必须在定义时就初始化因此必须在初始化列表内初始化。3 尽量使用初始化列表初始化因为不管是否使用初始化列表虽然对于内置类型没有差别但是对于自定义类型成员变量一定会先使用初始化列表初始化。为什么会先使用初始化列表初始化如下Date类没有默认构造函数因为26行的构造函数不属于默认构造函数中的任意一种在对Date类的对象d进行初始化时会调用Date类的默认构造函数所以对象d的day实参12和hour实参12都没有被传进去_t作为Date类的自定义类型成员变量会调用Time类的默认构造函数_hour默认传参为0因此打印_hour的值也为0