C++的初始化顺序很是重要,牢记才能不出常识性的错误。ios
其初始化顺序为:函数
1 类中的static成员是最早初始化的,这个是先于main函数的执行的,可是必须注意,若是这个成员只是在类中声明,而没有在类外边进行定义的话,那么这个是不会开辟内存的,是不会初始化的。测试
2 调用基类的构造函数。可是基类分为两种顺序,特别注意。一种是虚继承的基类;另外一种是普通继承的虚基类和普通基类。spa
虚继承的基类的构造函数是最早调用的,接着虚基类和普通基类的构造函数是按顺序执行的(按照继承的顺序,而不是在类的构造函数中的初始化顺序)。code
3 类的数据成员进行初始化,若是是类类型的数据成员就会调用相应的默认构造函数。注意这个顺序是根据类中数据成员定义出现的顺序进行初始化的。继承
4 最后是进入类本身的构造函数的代码执行
内存
以下的测试代码:
string
#include <iostream> #include <string> using namespace std; //抽象类A class A { public: A() { cout << "抽象类A的构造函数" << endl; } //纯虚函数fun virtual void fun1() = 0; }; //抽象类B class B { public: B() { cout << "抽象类B的构造函数" << endl; } //纯虚函数fun virtual void fun2() = 0; }; //普通类C class C { public: C() { cout << "类C的构造函数" << " 用于虚继承的" << endl; } }; //普通类D class D { public: D() { cout << "类D的构造函数" << " 用于虚继承的" << endl; } }; //普通类C class E { public: E() { cout << "类E的构造函数" << endl; } }; //普通类D class F { public: F() { cout << "类F的构造函数" << endl; } }; //普通类D class G { public: G() { cout << "类G的构造函数" << endl; } }; //普通类D class H { public: H() { cout << "类H的构造函数" << endl; } }; //普通类D class M { public: M() { cout << "类M的构造函数" << endl; } }; class Test : public E, public A, public F, public B, virtual public C, virtual public D { public: Test() :B(), A(), D(), C(), F(), E() { cout << "类Test的构造函数" << endl; } void fun1() { } void fun2() { } private: G g; // 会自动调用这个数据成员的构造函数 static H h; static M m; }; H Test::h; // 注意这个定义,很是重要,这就是static类型的成员变量的实现方式 int main(int argc, char* argv[]) { cout << "main begin" << endl; Test test; cout << "main end" << endl; return EXIT_SUCCESS; }
这个程序的运行结果以下:io