C++的初始化顺序非常重要,牢记才能不出常识性的错误。
其初始化顺序为:
1 类中的static成员是最先初始化的,这个是先于main函数的执行的,但是必须注意,如果这个成员只是在类中声明,而没有在类外边进行定义的话,那么这个是不会开辟内存的,是不会初始化的。
2 调用基类的构造函数。但是基类分为两种顺序,特别注意。一种是虚继承的基类;另一种是普通继承的虚基类和普通基类。
虚继承的基类的构造函数是最先调用的,接着虚基类和普通基类的构造函数是按顺序执行的(按照继承的顺序,而不是在类的构造函数中的初始化顺序)。
3 类的数据成员进行初始化,如果是类类型的数据成员就会调用相应的默认构造函数。注意这个顺序是根据类中数据成员定义出现的顺序进行初始化的。
4 最后是进入类自己的构造函数的代码执行
如下的测试代码:
1#include <iostream> 2#include <string> 3using namespace std; 4 5//抽象类A 6class A 7{ 8public: 9 A() 10 { 11 cout << "抽象类A的构造函数" << endl; 12 } 13 //纯虚函数fun 14 virtual void fun1() = 0; 15}; 16 17//抽象类B 18class B 19{ 20public: 21 B() 22 { 23 cout << "抽象类B的构造函数" << endl; 24 } 25 //纯虚函数fun 26 virtual void fun2() = 0; 27}; 28 29//普通类C 30class C 31{ 32public: 33 C() 34 { 35 cout << "类C的构造函数" << " 用于虚继承的" << endl; 36 } 37}; 38 39//普通类D 40class D 41{ 42public: 43 D() 44 { 45 cout << "类D的构造函数" << " 用于虚继承的" << endl; 46 } 47}; 48 49//普通类C 50class E 51{ 52public: 53 E() 54 { 55 cout << "类E的构造函数" << endl; 56 } 57}; 58 59//普通类D 60class F 61{ 62public: 63 F() 64 { 65 cout << "类F的构造函数" << endl; 66 } 67}; 68 69//普通类D 70class G 71{ 72public: 73 G() 74 { 75 cout << "类G的构造函数" << endl; 76 } 77}; 78 79//普通类D 80class H 81{ 82public: 83 H() 84 { 85 cout << "类H的构造函数" << endl; 86 } 87}; 88//普通类D 89class M 90{ 91public: 92 M() 93 { 94 cout << "类M的构造函数" << endl; 95 } 96}; 97 98class Test : public E, public A, public F, public B, virtual public C, virtual public D 99{ 100public: 101 Test() :B(), A(), D(), C(), F(), E() 102 { 103 cout << "类Test的构造函数" << endl; 104 } 105 void fun1() 106 { 107 } 108 void fun2() 109 { 110 } 111private: 112 G g; // 会自动调用这个数据成员的构造函数 113 static H h; 114 static M m; 115}; 116 117H Test::h; // 注意这个定义,非常重要,这就是static类型的成员变量的实现方式 118 119int main(int argc, char* argv[]) 120{ 121 cout << "main begin" << endl; 122 Test test; 123 cout << "main end" << endl; 124 return EXIT_SUCCESS; 125}
这个程序的运行结果如下:
