当你写下一个constructor时,你有机会设定class members的初值。有两种方法:
1.使用member initialization list
2.在constructor函数本身之内
有四种情况,为了让你的程序能够顺利编译,必须使用member initialization list:
(1) 当初始化一个reference member 时
(2) 当初始化一个const member 时
(3) 当调用一个base class的constructor,而它拥有一组参数时
(4) 当调用一个member class的constructor,而它拥有一组参数时
在这四种情况中,如果在constructor函数体内初始化,程序可以被正确编译并执行,但是效率不彰。
member initialization list
编译器会一一操作initialization list,以适当次序在constructor之内安插初始化操作,并且在任何explicit user code之前。
注意:list中的项目次序是由class中的member声明次序决定的,不是由initialization list中的排列次序决定的。
“初始化次序”和“initialization list中的项目排列次序”之间的外观错乱,会导致意想不到的危险。
class X
{
int i;
int j;
public:
x(int val):j(val),i(j){}
...
}
上述问题在于,由于声明次序的缘故,initialization list中的i(j)其实比j(val)更早执行。但因为j一开始未有初值,所以i(j)的执行结果导致i无法预告其值。
正确做法:
class X
{
int i;
int j;
public:
x(int val):j(val){i = j;}
...
}
j的初始化代码会安插在explicit user assignment 操作之前。