2

仮想継承を使用して、通常のダイヤモンドの問題を通常の方法で「解決」しようとすると、奇妙な問題が発生しました。

  A
 / \* both virtual
B   C
 \ /
  D

ただし、基本クラス A にはデフォルトのコンストラクターがないため、D から手動で呼び出す必要がありました。ただし、このダイヤモンドにクラス E を C 継承として追加しようとすると、

  A
 / \* both virtual
B   C
 \ / \
  D   E

E コンストラクターで A のコンストラクターを手動で呼び出す必要があります。つまり、多重継承もダイヤモンド ACE もありませんが、C は E から A を作成するものではありません。

class A                     
   {public: 
      A (int _N): N(_N) {};
      void show()
        {cout<<"A"<<N;} 
    protected:
      int N;
   }; 
class B: public virtual A   
   { public: 
       B(int n): A(2*n) {};
       void show()
        { cout<<"B"<<N;} 
   }; 
class C: public virtual A   
   { public: 
       C(int n): A(3*n) {};
       void show()
        { cout<<"C"<<N;} 
   }; 
class D: public B,C 
   { public: 
       D(): B(1), C(2), A(3) {};
       void show()
        { cout<<"D"<<N;} 
   }; 

class E: public virtual C
   { public:
       E(): C(1) {};
       void show()
        { cout<<"E"<<N;} 
   }; 

int main()
  {D d;       // OK
   A *a = &d; 
   a->show(); 

   E e;        // NOT OK, no function A::A() to call in E::E()
   A *a2 = &e;
   a2->show();
   return 0;
  } 

E から A のコンストラクターを呼び出さずにこの問題を解決することは可能ですか? 適切に行うにはCが必要です:-)。

または、ダイヤモンドの問題をまったく解決しようとしないことは可能ですか?

A   A
|   |  no virtual at all
B   C
 \ / \
  D   E

それでも、Aの2つのインスタンスでクラスDのオブジェクトを宣言しようとしますが、毎回Dから照合するときにコンパイラにCのAを使用するように指示しますか? 追加しようとすると

using C::A

D の宣言では、明確な基数 A のエラーが発生します。

4

2 に答える 2

3

E から A のコンストラクターを呼び出さずにこの問題を解決することは可能ですか? 適切に行うにはCが必要です:-)。

最も派生したクラス (この場合はE) のコンストラクターは、すべての仮想基底クラスのコンストラクターを呼び出す責任があります。

のコンストラクターは、最派生クラスではないためC、 のコンストラクターを呼び出すことはできません。仮想基底クラスは、直接基底クラスの前に初期化されるため、初期化する前にによって初期化する必要があります。ACEAC

于 2010-07-18T19:43:01.593 に答える
3

はい、仮想基本クラスのコンストラクター呼び出しは、仮想関数のオーバーライドとは異なります。

  • 派生クラスで仮想関数をオーバーライドできます。
  • 関数が基本クラスの 1 つでオーバーライドされ、他のクラスではオーバーライドされない場合にのみ、仮想関数をオーバーライドする必要があります。
  • 基本クラス コンストラクターの仮想基本クラスの init-list をオーバーライドすることはできません。

これは、次のことを意味します。

  • 仮想関数のオーバーライドに関する限り、仮想継承は単一継承にはまったく影響しません。
  • ただし、基本クラスのコンストラクター呼び出しに関しては、仮想継承はすべての派生クラスに影響します。
于 2011-11-02T22:46:54.387 に答える