class A { public: A(int n){ cout << "A ..." << endl; } ~A(){} }; class B { public: B(int n){ cout << "B ..." << endl; } ~B(){} }; class MyClass { public: MyClass(); ~MyClass(){} private: B m_b; A m_a; int m; string m_str; int n; }; MyClass::MyClass():m_a(1),m_b(2) { n = 100; m = 99; m_str = "138182"; cout << "MyClass ..." << endl; }
说明:成员被初始化的顺序,与初始化列表里面的顺序没有关系,只和成员的声明顺序有关。先声明的,先初始化。
class A { public: A(){ cout << "A ...无参构造函数" << endl; } A(int n){ cout << "A ...有参构造函数" << endl; } A(const A& a){ cout << "A ...拷贝构造函数" << endl; } A& operator = (const A& a){ cout << "A ...赋值运算符" << endl; return *this; } ~A(){} }; class B { public: B(){ cout << "B ...无参构造函数" << endl; } B(int n){ cout << "B ...有参构造函数" << endl; } B(const B& b){ cout << "B ...拷贝构造函数" << endl; } B& operator = (const B& b){ cout << "B ...赋值运算符" << endl; return *this; } ~B(){} }; class MyClass { public: MyClass(); ~MyClass(){} private: B m_b; A m_a; int m; string m_str; }; MyClass::MyClass() { cout << "MyClass ...进入函数体" << endl; m = 99; m_str = "138182"; m_a = 1; m_b = 2; }
运行结果:
1.内置数据类型,复合类型(指针,引用)
在成员初始化列表中初始化,和在构造函数体内赋值,性能和结果完全一样。
2.用户定义类型(类类型)
结果上相同,但是性能上存在很大的差别。因为类类型的数据成员对象在进入函数体前已经构造完成,也就是说在成员初始化列表处进行构造对象的工作,调用构造函数,在进入函数体之后,进行的是对已经构造好的类对象的赋值,又调用个拷贝赋值操作符才能完成(如果并未提供,则使用编译器提供的默认按成员赋值行为)
总结:
1、初始化列表中的初始化顺序:
只与类成员的声明顺序有关
2、初始化列表与构造函数体内初始化的区别: (内置数据类型除外)
(1)初始化列表中:直接调用成员的构造函数进行初始化;
(2)构造函数体中:成员对象在进入函数体之前(即在初始化列表处)完成构造,必须得有合适的构造函数可用(无参数的构造函数,或有默认参数的构造函数);
进入函数体之后,再对=右侧的数据调用构造函数,然后调用赋值运算符,给类成员赋值(一般情况下,类有默认赋值运算符)