14

C++での構築と初期化の順序の保証について疑問があります。たとえば、次のコードには4つのクラス、、、XおよびがありYます。main関数は、のオブジェクトを含む、のオブジェクトをインスタンス化し、から派生するため、両方のコンストラクターが呼び出されます。さらに、 'sコンストラクターに渡されたパラメーターは、暗黙的にのオブジェクトに変換されるため、'sコンストラクターも呼び出す必要があります。ZWclass Xclass Yclass Zconst char*Xclass WW

C ++標準がコピーコンストラクターの呼び出しの順序に与える保証は何ですか?または、同等に、このプログラムは何を印刷できますか?

#include <iostream>

class Z {
   public:
   Z() { std::cout << "Z" << std::endl; }
};

class Y {
   public:
   Y() { std::cout << "Y" << std::endl; }
};

class W {
   public:
   W(const char*) { std::cout << "W" << std::endl; }
};

class X : public Z {
   public:
   X(const W&) { std::cout << "X" << std::endl; }
   private:
   Y y;
};

int main(int, char*[]) {
   X x("x");
   return 0;
}

編集:これは正しいですか?

   W      |
 /   \    |
Z     Y   |
 \   /    |
   X      V
4

5 に答える 5

23

すべてのクラスで、構築順序が保証されます。左から右に指定された基本クラスの後に、クラス定義で宣言された順序のメンバー変数が続きます。クラスのコンストラクター本体は、そのベースとメンバーのすべての構築が完了すると実行されます。

あなたの例Xでは、から派生しZて含まれているYので、Z最初にベースオブジェクトが構築され、次にYメンバーが構築され、次にコンストラクター本体の実行でコンプリートyの構築が完了します。XX

Wのコンストラクターに渡すには一時的なものが必要なXので、の構築が始まる前に構築され、初期化が完了xすると破棄されます。x

したがって、プログラムは次のように出力する必要があります。

W
Z
Y
X
于 2010-03-25T15:57:54.653 に答える
8

1)まず、引数を計算する必要があります。

2)次に基本クラスが構築されます。

3)次に、クラスの宣言に出現する順序でメンバーが作成されます。

4)次に、Xのコンストラクターが呼び出されます

于 2010-03-25T15:54:02.730 に答える
2
  1. Wオブジェクトは、Xのコンストラクターが呼び出される前に作成されます。
  2. Xの基本クラスとしてのZは、Xのメンバーの前に初期化されます。
  3. Yは、メンバーの初期化中に初期化されます
  4. Xのコンストラクターが実行されます。
于 2010-03-25T15:54:54.877 に答える
2

Charles Baileyの答えを拡張するために、基本クラスが仮想的に継承されるときにルールが変更されます。私はいつも順序を忘れています。IBMのサイトでは、仮想ベースが最初に初期化されると言っていますが、実際には雑学以上のケースに遭遇したことはありません。

于 2010-03-25T17:26:52.840 に答える
2

これらを要約すると、次のルールがあります。

  1. 引数、右から左へ
    a。右端
    b。右から2番目
  2. 基本クラス
  3. 仮想ベース
  4. 左から右への基本クラス
  5. クラスでの宣言順のメンバー
  6. 呼び出されたクラスのコンストラクタ
于 2015-08-26T08:05:58.340 に答える