- 对象的创建分两步:
- 数据成员初始化(初始化列表)。
- 执行被调用构造函数体内的动作。
- 通过初始化列表可显示调用父类构造函数。
1 #include "stdafx.h" 2 #include <iostream> 3 using namespace std; 4 5 class A 6 { 7 public: 8 A(int i) 9 { 10 m_i = i; 11 cout<<"A(int i)"<<endl; 12 } 13 private: 14 int m_i; 15 }; 16 17 class B : public A 18 { 19 public: 20 B(int i):A(i) //调用父类构造函数 21 { 22 m_i = i; 23 cout<<"B(int i)"<<endl; 24 } 25 private: 26 int m_i; 27 }; 28 29 int _tmain(int argc, _TCHAR* argv[]) 30 { 31 B b(0); 32 33 return 0; 34 }
- 通过初始化列表类成员可以被显式初始化(即显示调用其构造函数:默认、有参和拷贝构造函数)。
- 成员初始化顺序与成员声明顺序相同,与初始化列表顺序无关!(参见《Effective C++ 2》条款13)。
- 保证同类的所有对象成员有同样的构造和析构顺序,减小开销(不必跟踪每一对象的成员初始化顺序)
- 尽量使用初始化而不要在构造函数里赋值 (参见《Effective C++ 2》条款12)。
- const 和引用成员必须通过初始化列表进行初始化(无法赋值)
- 对象成员最好通过初始化列表初始化(减少一次赋值操作)
- 少量内置数据类型成员可通过初始化列表初始化(便于维护,如改为const)
-
1 #include "stdafx.h" 2 #include <iostream> 3 using namespace std; 4 5 class A 6 { 7 public: 8 A(){cout<<"A()"<<endl;}; 9 A(int n){cout<<"A(int)"<<endl;}; 10 A(const A&){cout<<"A(const A&)"<<endl;}; 11 ~A(){cout<<"~A()"<<endl;}; 12 }; 13 14 class B 15 { 16 public: 17 //初始化列表:依次调用默认构造函数、有参构造函数和拷贝构造函数 18 B():m_a0(),m_a1(0),m_a2(m_a1){cout<<"B()"<<endl;}; 19 ~B(){cout<<"~B()"<<endl;}; 20 private://初始化顺序同声明顺序 21 A m_a0; 22 A m_a1; 23 A m_a2; 24 }; 25 26 int main(int argc, char* argv[]) 27 { 28 { 29 B b; 30 } 31 32 return 0; 33 }
- 参考《Effective C++ 2》、《C++Primer》、《Thinking in C++》