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