C ++
 Computer >> コンピューター >  >> プログラミング >> C ++

C++のコンストラクター内で仮想関数を呼び出す


コンストラクタまたはデストラクタから呼び出す仮想関数は危険であり、呼び出す仮想関数は派生クラスからではなく基本クラスから呼び出されるため、可能な限り避ける必要があります。

その理由は、C ++では、スーパークラスは派生クラスの前に構築されるためです。したがって、次の例では、Dがインスタンス化される前に、Bがインスタンス化される必要があるためです。 Bのコンストラクターが呼び出されたとき、それはまだDではないため、仮想関数テーブルにはBのs()のコピーのエントリがまだあります。

サンプルコード

#include<iostream>
using namespace std;
class B {
   public: B() {
      s();
   }
   virtual void s() {
      cout << "Base" << endl;
   }
};

class D: public B {
   public: D() : B() {}
   virtual void s() {
      cout << "Derived" <<endl;
   }
};

int main() {
   D de;
}

出力

Base

  1. C++のコンストラクタ

    コンストラクターは、クラスの新しいオブジェクトが作成されたときに実行されるクラスの関数です。コンストラクターはクラスと同じ名前であり、戻り型はなく、voidでさえありません。これらは主に、クラスの変数の初期値を提供するのに役立ちます。 コンストラクターの2つの主なタイプは、デフォルトのコンストラクターとパラメーター化されたコンストラクターです。これらの詳細は次のとおりです。 デフォルトコンストラクタ デフォルトのコンストラクターはパラメーターを取りません。デフォルトのコンストラクターがプログラマーによって明示的に提供されていない場合、コンパイラーは暗黙のデフォルトのコンストラクターを提供し

  2. C ++のコンストラクター内で仮想関数を呼び出す方法は?

    コンストラクタまたはデストラクタから仮想関数を呼び出すことは危険であり、可能な限り避ける必要があります。これは、呼び出す仮想関数が派生クラスではなく基本クラスから呼び出されるためです。 C ++では、すべてのクラスが独自の構造に入る前に、そのバージョンの仮想メソッドテーブルを構築します。したがって、コンストラクターで仮想メソッドを呼び出すと、Baseクラスの仮想メソッドが呼び出されます。または、そのレベルで実装がない場合は、純粋仮想メソッド呼び出しが生成されます。 Baseが完全に構築されると、コンパイラはDerivedクラスの構築を開始し、Derivedクラスの実装を指すようにメソッドポイ