C++学习笔记24:构造函数初始化列表
目录
一、什么是初始化列表?
二、初始化列表和函数体内赋值有什么区别
三、哪些成员必须使用初始化列表
1. const 成员变量
2. 引用成员变量
3. 没有默认构造函数的自定义类型成员
四、初始化顺序
五、小结
一、什么是初始化列表?
在C++中,构造函数除了可以在函数体内给成员变量赋值,也可以使用初始化列表。
普通写法:
class Date { public: Date(int year, int month, int day) { _year = year; _month = month; _day = day; } private: int _year; int _month; int _day; };初始化列表写法:
class Date { public: Date(int year, int month, int day) ; _year(year) , _month(month) , _day(day) { } private: int _year; int _month; int _day; };初始化列表写在构造函数参数列表后面,以冒号 : 开始,多个成员之间用逗号分隔。
二、初始化列表和函数体内赋值有什么区别
函数体内写:
_year = year;本是上是赋值。
初始化列表写:
: _year(year)本质上是初始化。
简单理解:
初始化列表:成员函数创建时直接初始化 函数体内赋值:成员变量创建后再赋值对于普通变量 int、char、double成员你,两种写法很多时候结果一样。
但有些成员必须使用初始化列表。
三、哪些成员必须使用初始化列表
主要有三类:
1. const 成员变量 2. 引用成员变量 3. 没有默认构造函数的自定义类型成员1. const 成员变量
class A { public: A(int x) : _x(x) { } private: const int _x; };const 成员变量创建后不能修改,所以必须在初始化列表中初始化。
2. 引用成员变量
class A { public: A(int x) : _ref(x) { } private: int& _ref; };引用必须在定义时初始化,所以引用成员也必须使用初始化列表。
3. 没有默认构造函数的自定义类型成员
class B { public: B(int x) : _x(x) { } private: int _x; }; class A { public: A(int x) : _b(x) { } private: B _b; };因为 B 没有无参构造函数,所以 A 中的 _b 必须在初始化列表中显式初始化。
四、初始化顺序
成员变量的初始化顺序不是看初始化列表中的书写顺序,而是看成员变量在类中的声明顺序。
例如:
class A { public: A(int x) : _a1(x) , _a2(_a1) { } private: int _a2; int _a1; };虽然初始化列表中先写 _a1,但成员变量声明时 _a2 在前,所以实际会先初始化 _a2。
因此建议:
初始化列表的书写顺序和成员变量的声明顺序保持一致。
这样代码更清晰,也不容易出错。
五、小结
本篇主要学习了构造函数初始化列表。
需要记住:
- 初始化列表写在构造函数参数列表后面;
- 初始化列表以 : 开始;
- 多个成员变量之间用逗号隔开;
- 函数体内是赋值,初始化列表才是初始化;
- const 成员变量必须使用初始化列表;
- 引用成员变量必须使用初始化列表;
- 没有默认构造函数的自定义类型成员必须使用初始化类表;
- 成员变量初始化顺序由声明顺序决定;
- 初始化列表书写顺序建议和成员声明顺序保持一致;
- 建议优先使用初始化列表写构造函数。
初始化列表是构造函数中的重要内容。理解它之后才能更好的处理 const 成员、引用成员和自定义类型成员的初始化问题。
