2017-07-12 14 views
0

私はStroustrup氏による「デザインと進化のC++」に次のコードを見つけました:複数の仮想(ダイヤモンド)継承

class W 
{ 
public: 
    virtual void f(); 
    virtual void g(); 
}; 

class AW : public virtual W 
{ 
public: 
    void g() {} 
}; 

class BW : public virtual W 
{ 
public: 
    void f() {} 
}; 

class CW: public AW, public BW ***, public virtual W*** 
{ 

}; 

CW* pcw = new CW; 
AW* paw = pcw; 
BW* pbw = pcw; 

void fff() 
{ 
    pcw->f(); //invokes BW:f() 
    pcw->g(); //invokes AW:g() 
    paw->f(); //invokes BW:f() ! 
    pbw->g(); //invokes AW:g() ! 
} 

それはすなわちミックスインの動作を例示しています。共通の基盤に振る舞いを加え、 "お互いを知っている"異なるクラス。

なぜCWが直接Wから(、パブリック仮想W)を継承していますか? 私はVC2015の有無にかかわらず試しましたが、同じクラスレイアウトを生成します。

+0

「W」のインスタンスを1つだけ継承するようにしますか? – Charles

+1

@Charles私はAWのWからの仮想継承を考えており、BWはこれを担当しています。 – Mart

答えて

1

Stroustrup氏(21.3.5、ページ632)によるC++プログラミング言語(第4版)から:オブジェクトの

すべての部品は[CW] [W]の単一コピーを共有しなければなりません。そうでなければ、[W]から何かを2回取得することができます...複製を避けるために基底を宣言しますvirtual:派生クラスのすべてのvirtualは同じ(共有)オブジェクトで表されます。


Iを有するとなしの両方VC2015に試み、それが同じクラスのレイアウトを生成します。

Wにはレプリケートするインスタンス変数がないため、このケースではそれほど重要でない理由があります。とにかくW内のすべてのメソッドはvirtualと宣言されました。

+0

Wが直接継承ツリーに存在し、CWがそれが持つ可能性のある関数やインスタンス変数にアクセスできる場合、Wを直接継承したいのですが? – Mart

+0

'AW'と' BW'はあなたがする必要があるかどうかわかりません... – Charles