コンストラクターでの仮想関数のオーバーライド
次のコード スニペットを考えてみましょう:
#include <iostream> struct base { virtual const int value() const { return 0; } base() { // Default constructor std::cout << value() << std::endl; } }; struct derived : public base { virtual const int value() const { return 1; } }; int main() { derived d; // Declares an instance of the derived class }
このコードを実行すると、期待される 1 の代わりに 0 が出力されます。なぜですか?
構築中の仮想関数呼び出し
基底クラスのコンストラクターがコンストラクター内で仮想関数を呼び出すと、仮想関数はインスタンスではなく基底クラスのインスタンスで呼び出されます。派生クラスのインスタンス。これは、構築中のオブジェクトの「成熟」プロセスの結果です。
この例では、オブジェクトが部分的に構築されたときに、基本コンストラクターが value() を呼び出します。この時点では、オブジェクトはまだ派生オブジェクトに「成熟」していません。したがって、value() の元の基本実装が呼び出されます。
問題の修正方法
コードに 1 を出力させるには、仮想関数の呼び出しを回避できます。コンストラクター内で。これは次の方法で実現できます:
ポインターの使用: メンバー関数から直接ではなく、基本クラスへのポインターまたは参照から仮想関数を呼び出します:
base* b = new derived(); b->value(); // Calls the derived class implementation delete b;
メンバーの初期化の使用リスト: メンバー初期化リストを使用して、コンストラクターで仮想関数の値を明示的に指定します:
derived d : base() { } // Initializes `base()` and the virtual function // call to occur within the constructor
以上が基本クラスのコンストラクターで仮想関数を呼び出すと、基本クラスの実装が使用されるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。