#include <iostream> using namespace std; int seti() {cout << "seti" << endl;return 1;} int setj() {cout << "setj" << endl;return 1;} class a { public: a() {cout << "a()~~~~~" << endl;} }; class b { public: b():j(setj()),i(seti()) {cout << "b()~~~~~" << endl;} int i; a ca; int j; }; int main() { b ob; return 0; }
运行结果:
可以看出成员被初始化的顺序和成员初始化表里面的顺序是没有关系的,只和成员的声明顺序有关。
总结一下:要判断b类的对象ob的成员初始化顺序,
1.先找出构造函数头后的显示成员初始化表,这里是 j(setj()),i(seti()) ,
2.接下来再找出隐式成员初始化列表,只有ob.a是一个类的对象,所以最后的成员初始化表就是 j(setj()),i(seti()),oa(a())
3.这三个成员的初始化顺序是 i、ca、j,所以初始化顺序是 i先被初始化,然后是ca被初始化,最后是j被初始化,再然后是构造函数体内的语句被执行。
构造函数的成员初始化表(显示+隐式)和构造函数体内的区别是:先执行成员初始化表然后再执行构造函数体内的语句。
对于const类型和引用类型的成员只能在成员初始化表初始化,以及在类定义中初始化(static const类型还可以在类定以外的程序文本中初始化);
对于基本类型的成员在成员初始化表中初始化和函数体内赋值的效果是一样的,若显示初始化表里面没有基本类型的成员,那么不会把他放入隐式初始化表里面;
对于类类型的成员,如果没有出现在显示初始化表里面,则会放入隐式初始化表里面。