クラス内のメンバー変数の初期化順序

4576 ワード

クラス内のメンバー変数の初期化に注意してください:
考慮:
#include<iostream>
using namespace std;

class A
{
private:
    int n1;
    int n2;
    
public:

    A():n2(0),n1(n2+2){} 
    
    void Print(){
        cout << "n1:" << n1 << ", n2: " << n2 <<endl;  
    }
};

int main()
{

    A a;
    a.Print();

    getchar();
    return 1;
}

以上の結果を出力する場合、n 1:2、n 2:0かと思います
間違いだ!
#include<iostream>
using namespace std;

class A
{
private:
    int n1;
    int n2;
    
public:

    //A():n2(0),n1(n2+2){} //n1:-858993458, n2: 0
    //A():n1(n2+2),n2(0){}    //n1:-858993458, n2: 0
    //A():n1(0),n2(n1+2){}//n1:0, n2: 2
    A():n2(n1+2),n1(0){}//n1:0, n2: 2

    void Print(){
        cout << "n1:" << n1 << ", n2: " << n2 <<endl;  
    }
};

int main()
{

    A a;
    a.Print();

    getchar();
    return 1;
}

以上の例を実行してみると,T():name(),name 2():{}の形式で初期化を行う場合,初期化の順序はクラス内の本来のクラスの変数位置の順序に関係し,T():name(),name 2():{}の形式における変数名の順序とは無関係であることが分かる.
 
どうしてこんなことをするの?なぜC++は初期化リストの順にメンバー変数を初期化しないのですか? 
初期化の順序は,析出の順序とは逆であるべきであること,すなわち,2つのメンバ変数AとBがあり,初期化の順序がA->Bである場合,このクラスが析出される際には,まずBを析出してAを再析出すべきであることを知っているからである.1つのクラスにはconstructorが複数ある可能性があり、初期化リストも複数あるので、初期化リストの順序で初期化する場合は、この順序を覚えて、解析時に解析の順序を決定しなければなりません.したがってC++は簡単な点の方法を選択し,メンバ変数が現れる順に初期化する.
まとめ:それなら、初期化リストを書くときは、メンバー変数が現れる順序で書くと、混同しにくくなります.
参考:effective C+,http://blog.sinzy.net/hjk41/entry/7998