2017-04-22 4 views
0

の順序について:いくつかの混乱が、私は次のコードを持つコンストラクタの呼び出しと継承

class A { 
    public: 
     A() { cout << "A-C" << endl; } 
     ~A(){ cout << "A-D" << endl; } 
}; 

class B { 
    public: 
     B() { 
      cout << "B-C" << endl; 
     } 
     ~B() { 
      cout << "B-D" << endl; 
     } 
}; 

class C { 
    protected: 
     A* a; 
     B b; 
    public: 
     C() { 
       a = new A; 
       cout << "C-C" << endl; 
      } 
     ~C() { 
      delete a; 
      cout << "C-D" << endl; 
     } 
}; 

class D : public C { 
    protected: 
     A a; 
     B b; 
    public: 
     D(){ cout << "D-C" << endl; } 
     ~D(){ cout << "D-D" << endl; } 
}; 

int main() { 
    D* d = new D; 
    B* b = new B; 

    delete b; 
    delete d; 

    system("pause"); 
    return 0; 
} 

出力上の私の最初の考えは以下の通りであった。

A-C 
C-C 
A-C 
B-C 
D-C 
B-C 
B-D 
D-D 
B-D 
A-D 
A-D 
C-D 

しかし、それは間違っているのです。 出力は実際には次のとおりです。プログラムは最後に、最初にBのコンストラクタとデストラクタ呼び出して、なぜ私にはわからない

B-C 
A-C 
C-C 
A-C 
B-C 
D-C 
B-C 
B-D 
D-D 
B-D 
A-D 
A-D 
C-D 
B-D 

。 私はコンストラクタの呼び出し順序は次のようにするべきだと思います: Cのコンストラクタ - > Aのコンストラクタ - > Bのコンストラクタ - > Dのコンストラクタです。

とデストラクタ呼び出しの順序は、コンストラクタ呼び出しの逆順

誰もが私にBのコンストラクタが最初に呼び出され、Bのデストラクタが最後に呼び出された理由を伝えることができるのですか?

+1

待って、なぜ出力が 'B-C'になるのですか? 'new D'は' A'コンストラクタを呼び出す 'C'コンストラクタを呼び出します。 –

+1

@GillBates nuh-huh。 'C'はコンストラクタのボディの前に初期化された' B'データメンバを持っています。 – Quentin

+0

@Quentin私は 'C'の' B'データメンバがポインタだと思っていました。 –

答えて

1
B-C 
A-C 
C-C 
A-C 
B-C 
D-C 

これらはすべてD* d = new D;によって引き起こされます。

Dコンストラクタは、CDのベースであるため、Cコンストラクタを呼び出します。

そして、クラスCのデータメンバーabが初期化され、aのでコンストラクタがまだそのデータメンバーを要求しないポインタです。 bはタイプBのオブジェクトなので、Bパラメータのないコンストラクタが呼び出され、最初にB-Cが与えられます。


はその後 Cコンストラクタで、あなたはあなたの C-C続い A-Cを与える Aのコンストラクタを呼び出し new Aを言います。

次に、データメンバーaおよびクラスDのbが初期化され、両方があなたにA-CB-Cを与えるので、両方のコンストラクタが呼び出されたオブジェクトが、あります。

そして最後に、というコンストラクタが呼び出され、D-Cで終了します。

+0

ありがとうございます。クラスが別のクラスを継承するとき、DがCから継承するとしましょう。まず、基本クラスのデータメンバーを初期化し、データメンバーの初期化後にコンストラクターが呼び出されます。 –

+0

@KelvinNgはい、正確です。 –

関連する問題