C++笔记(7)成员初始化列表
成员初始化列表由逗号分隔的初始化列表组成(前面带冒号),它位于参数列调的右括号之后,函数体左括号之前。如果数据成员的名称为mdata,并需要将它初始化为val,则初始化器为mdata(val).
Classy::Classy(int val) : mdata(val)
以下三种情况下需要使用初始化成员列表:
1. 需要初始化const修饰的类成员或初始化引用成员数据;
2. 需要初始化的数据成员是对象的情况(这里包含了继承情况下,通过显示调用父类的构造函数对父类数据成员进行初始化);
3. 子类初始化父类的私有成员;
1. 需要初始化const修饰的类成员或初始化引用成员数据
1)初始化const修饰的类成员
下面为一个队列类,
class Queue { private: struct Node {Item item; struct Node* next;}; enum { Q_size = 10 }; Node* front; Node* rear; int items; const int qsize; public: Queue(int qs = Q_size); ~Queue(); };
应该将队列的最大长度qsize设置为构造函数参数qs的值。
下面的实现方法无法正常运行:
Queue::Queue(int qs) { front = rear = nullptr; items = 0; qsize = qs; }
这是由于,在调用构造函数时,首先会给成员变量开辟内存,然后通过常规赋值将值存储到内存中。而qsize是常量,可以对它进行初始化,但不能给它赋值。因此,对于const数据成员,必须在执行到构造函数体之前,即创建对象时进行初始化。
使用成员初始化列表,可以这样编写Queue的构造函数:
Queue::Queue(int qs) : qsize(qs) { front = rear = nullptr; items = 0; }
通常,初值可以是常量或构造函数的参数列表中的参数。这种方法并不限于初始化常量,可以将Queue的构造函数写成如下所示:
Queue::Queue(int qs) :qsize(qs), front(nullptr), rear(nullptr), items(0) { }
2)初始化引用成员数据
对于被声明为引用的类成员,也必须使用这种语法:
class Agency{...}; class Agent { private: Agency & belong; ... }; Agent::Agent(Agency & a) : belong(a){...}
这是因为引用和const数据类似,只能在被创建时进行初始化。对于简单数据成员(例如front和items),使用成员初始化列表和在函数体中赋值没有什么区别。然而,对于本身就是类对象的成员来说,使用成员初始化列表的效率更高。
参考:1.《c++ primer plus》p378
2. https://blog.csdn.net/sinat_20265495/article/details/53670644