2017-04-05 14 views
0

は、私はこの質問がありました仮想基底クラスと継承

#include <iostream> 

using namespace std; 

class base 
{ 
    public: 
     base() 
     { 
     cout << "ctor in base class\n"; 
     } 
}; 

class derived1 : public base 
{ 
    public: 
     derived1() 
     { 
     cout <<"ctor in derived class\n"; 
     } 
}; 

int main() 
{ 
    derived1 d1obj; 
    return 0; 
} 

この質問を見つけました: - d1objが作成されると、制御は最初の基底クラスのコンストラクタに達し、それが派生しに行きますクラスのコンストラクタ?それとも逆のことですか?最初に派生クラスのコンストラクタに到達し、それが基底クラスを持つことがわかり、コントロールが基底クラスのコンストラクタに移動しますか?

とaswerの一部を含有

クラスが仮想塩基を有する場合、コンストラクタが放出される2人の異なる機能体を生じるすることが一般的です - このクラスは、最も派生型である場合に使用するための1つ、及びこのクラスが基本クラスである場合に使用するクラスその理由は、仮想基底クラスが最も派生したクラスによって構築されているため、共有されると一度しか構築されないためです。したがって、コンストラクタの最初のバージョンはすべての基本クラスコンストラクタを呼び出しますが、2番目のバージョンは非仮想ベースのコンストラクタのみを呼び出します。

誰でも私にこの例を説明できますか?クラスは、それが放出されている二つの異なる機能本体につながるために、コンストラクタのための共通の仮想基盤がある場合

Hereは、」その質問

+1

あなたの例には仮想基本クラスがないため、質問の太字のイタリック体の説明には使用できません。これは、クラスが派生する2つのクラスが同じ基本クラスを持つ仮想継承(「ダイアモンド継承」)専用のコンストラクタをコンパイラがどのように構築するかの特別なケースです。私は10年以上のプログラミングでC++を使用する必要はありませんでした(「ここでは仮想継承の例」を除く) –

答えて

0

ためのリンクです - このクラスは、ほとんどの派生型である使用のための1つを、そしてこのクラスがそれ自体が基本クラスである場合に使用するためのものです。その理由は、仮想基底クラスが最も派生したクラスによって構築されているため、共有時には一度しか構築されないためです。 2番目のバージョンは非仮想ベースのコンストラクタのみを呼び出すのに対し、すべての基本クラスのコンストラクタを呼び出します。

この回答者は、実際には複数の継承で恐ろしいダイヤモンドと呼ばれるC++の一般的な状況について言いたいと思います。ちょうどあなたの例では、このリンク In C++, what is a virtual base class?

1

に最もupvoted答えを見ることがbaseのデフォルトコンストラクタを呼び出すための責任があることderived1のデフォルトコンストラクタです。理解する derived1は、実際の(最も誘導される)オブジェクトである場合

int main() 
{ 
    derived1 d1obj; // Most derived object of type `derived1` 
    // It contains a direct `base` subobject 
    // Constructor of `derived1` must construct `base` subobject as well 
} 

しかしderived1が大きい物体

class derived2 : public derived1 
{ 
public: 
    derived2() 
    { 
    cout <<"ctor in derived 2 class\n"; 
    }  
}; 

int main() 
{ 
    derived2 d2obj; // Most derived object of type `derived2` 
    // It contains a direct `derived1` subobject and an indirect `base` subobject 
    // (through `derived1`) 
    // Constructor of `derived2` must directly construct both `derived1` subobject and 
    // `base` subobject 
    // Which means that constructor of `derived1` subobject should not attempt 
    // to construct `base` subobject 
} 

のベースサブオブジェクトを使用する場合、それはあなたの例のようにしかし、これは、必要なだけですderived2のコンストラクタは、デフォルトコンストラクタderived1とデフォルトコンストラクタbaseの両方を呼び出します。この場合、デフォルトのコンストラクタderived1になりません。baseの二重構築につながるため、baseのコンストラクタを呼び出すことはありません。

derived1には、デフォルトのコンストラクタの2つのバージョンがあります。元の例ではフルバージョンが呼び出され、上の例ではderived2から呼び出される「縮小」バージョンがあります。

また、derived1のデフォルトのコンストラクタは、baseのデフォルトのコンストラクタを呼び出すかどうかを示す隠しブールパラメータで実装できます。

関連する問題