1

重複の可能性:
gccc++仮想継承の問題

こんにちはすべて、私はスコットマイヤーズの本による効果的なC++を読んでいます。仮想基本クラスと仮想継承については、次のように述べられています。

仮想ベースクラスの初期化を管理するルールは、非仮想ベースのルールよりも複雑で直感的ではありません。仮想ベースを初期化する責任は、階層内で最も派生したクラスが担っています。新しい派生クラスが階層に追加されるとき、仮想ベース(直接および間接の両方)の初期化の責任を引き受ける必要があります

質問は上記のステートメントにあり、仮想ベースカルスの初期化のルールは何ですか?また、上記のテキストで述べたように、派生クラスがとらなければならない責任は何ですか。例を挙げて説明をお願いします。

ありがとう!

4

1 に答える 1

4

引用を例で説明しましょう。あなたがこれらのクラスを持っているとしましょう、

struct A {  A(int x) {} };
struct B : virtual A {  B(int x) : A(x) {} };
struct C : virtual A {  C(int x) : A(x) {} };

注:A仮想ベースです!

ここで、とDからの派生を定義します。BC

struct D : B, C 
{
  //correct constructor - because A(x) is "present" in the initialization-list
  D(int x) : A(x), B(x), C(x) { }

  //wrong constructor - because A(x) is "absent" from the initialization-list!
  //D(int x) :B(x), C(x) { }

};

は階層内で最もD派生したクラスであることに注意してください。したがって、初期化の責任はであり、そのため、コンストラクターの初期化リストに明示的に書き込みます(上記を参照)。とだけを書くと、コンパイルすらできなくなります。これを参照してください:http ://www.ideone.com/sO6m5 ADDA(x) B(x)C(x)

しかし、一度書くA(x)と、うまくコンパイルされます。これを参照してください:http ://www.ideone.com/kiwh0

ここでもう一度引用を読み、太字のテキストに注意してください。

仮想ベースクラスの初期化を管理するルールは、非仮想ベースのルールよりも複雑で直感的ではありません。仮想ベースを初期化する責任は、階層内で最も派生したクラスが担っています。新しい派生クラスが階層に追加されるとき、仮想ベース(直接および間接の両方)の初期化の責任を引き受ける必要があります

この説明がコンセプトの理解に役立つことを願っています!

于 2011-02-05T14:51:47.187 に答える