オブジェクト指向プログラミングで建設的な力と破壊的な力が収束するとき: クラス継承のケーススタディ
継承階層内でオブジェクトを作成するとき、コンストラクターとデストラクターが呼び出される順序に関して根本的な疑問が生じます。この調査は、基本クラスと派生クラスの両方の動作と、それらのクラス内のメンバー フィールドの影響を中心にしています。この謎を解明するために、具体的な例を詳しく見てみましょう。
次の C コード スニペットを考えてみましょう:
struct A { A() { std::cout << "A() C-tor" << std::endl; } ~A() { std::cout << "~A() D-tor" << std::endl; } }; struct B : public A { B() { std::cout << "B() C-tor" << std::endl; } ~B() { std::cout << "~B() D-tor" << std::endl; } A a; };
ここでは、A と B という 2 つのクラスがあり、B はクラスを継承しています。 A. クラス B 内では、型 A のメンバー フィールド a も定義されています。クラス B のインスタンスを作成する際、コンストラクター呼び出しとデストラクター呼び出しの順序が非常に重要になります。
構築の仕組み
コードが実行されると、オブジェクトの構築はその基本クラスから始まります。この場合、A クラスは B の基本クラスであるため、A() コンストラクターが最初に呼び出されます。これに続いて、派生クラスのメンバー フィールドが構築されます。クラス B には型 A のメンバー フィールド a があるため、この段階で A() コンストラクターが再度呼び出されます。最後に、派生クラス B() のコンストラクターが呼び出され、オブジェクトの構築が完了したことを示します。
破壊への降下
オブジェクトのライフサイクルが終了したとき最後に、デストラクター呼び出しの順序は逆のパターンに従います。メンバーフィールドは、宣言とは逆の順序で最初に破棄されます。この例では、クラス B のメンバー フィールド a (クラス A のインスタンス) のデストラクター ~A() が呼び出されます。これに続いて、派生クラス自体が破棄され、~B() の呼び出しがトリガーされます。最後に、基本クラスのデストラクター ~A() が呼び出されます。
初期化リストに関係なく
コンストラクターとデストラクターの呼び出しの順序に注目してください。初期化子リストの有無による影響を受けません。提供されているコード スニペットには初期化リストはありませんが、上記の呼び出し順序は依然として当てはまります。この一貫したパターンにより、さまざまな継承シナリオにわたって構築と破壊の予測可能なフローが保証されます。
以上がC の継承では、基本クラスと派生クラスでのコンストラクターとデストラクターの呼び出しの順序は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。