一、初始化列表的形式
class A {
public:
explicit A(int val) : _ma(val) {
cout << _ma << endl;
}
private:
int _ma;
};
class B {
public:
//初始化列表
B(int val1, int val2) : _a(val1), _aa(val2) {
}
private:
A _aa;
A _a;
};
二、对象的构造过程
step1:调用对应的构造函数;
step2:构造基类对象(在进入构造函数的大左括号之前);
step3:初始化成员变量(在进入构造函数的大左括号之前,如果没有初始化列表,就用成员变量的默认构造函数);
step4:进入构造函数内部执行语句;
step5:出构造函数,完成对象构造,此时才算一个可以使用的完整的对象。
三、使用初始化列表和不使用的区别
初始化列表一直都在,只是我们有时候省略了
1、初始化列表相当于由用户指定类的基类构造方式和成员变量初始化方式,如果不使用就会调用默认的构造函数进行基类和成员变量的初始化。
2、在构造函数内部进行的“成员变量初始化”,实际上是赋值,而不是初始化,因为在进入构造函数内部之前成员变量已经初始化完成,如下所示:
class Test{
public:
Test(){
a = 100; //这里不是a的初始化,而是赋值,a在一开始被初始化成了0;
}
private:
int a;
}
四、成员变量的初始化顺序
成员变量的初始化顺序是按照变量的定义顺序进行的,和初始化列表中变量的顺序无关,如下所示:
class B {
public:
B():_a(),__a() { //这里不管把哪个变量放在前面,初始化的顺序都是先_a后__a
cout << "B()" << endl;
}
private:
//变量的定义顺序
A _a;
A __a;
};
五、什么情况下必须使用初始化列表
1、const成员变量的初始化;
2、基类没有提供默认构造函数的时候。