C++中初始化的順序問題

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

相關文章
相關標籤/搜索