2

ここに画像の説明を入力してください

1つの親クラスがインターフェイス(仮想デストラクタを備えた純粋仮想関数のみを含む)である場合、多重継承を使用しても大丈夫ですか?

コンパイル速度を上げるために、インターフェイス部分(図の黄色のクラス)のみを公開したいと思います。緑の部分は実装部分です。しかし、CPetはCAnimal(is-a Relation)とIPet(implement)から継承する必要があり、「DiamondofDeath」があります:(

インターフェイスクラス(黄色)には純粋仮想関数と仮想破壊しかありません。したがって、ファクトリクラスを介してCDog、CCatを作成する場合、あいまいさなどの問題はありません。CDogには2つのvtable(IDogとCPetから)がありますが、仮想関数テーブルでは、ポイントは同じ関数(CDogメンバー関数)を示します。

コンパイルエラーも実行エラーもありません...しかし、私はこの階層について心配しています。大丈夫ですか、それとも問題ありませんか?

PS:「仮想継承」を使用したくないのは、それを使用すると、ウォッチビューからクラスメンバー変数を調べることができないためです(仮想継承がlinked-listのように親クラスにリンクしているためだと思います)。

環境:Visual Studio C++2008以降。

4

1 に答える 1

2

CPet上記の説明では、純粋仮想関数がvtableIAnimal::isAlive()で定義されていないため、のインスタンスをインスタンス化できないはずです。IPet

struct IAnimal {
    virtual ~IAnimal() {}
    virtual void isAlive() = 0;
};

struct IPet : public IAnimal {
};

struct CAnimal : public IAnimal {
    virtual void isAlive() {
    }
};

struct CPet : public CAnimal, public IPet {
};

int main(void) {
    CPet cp;
}

Visual C ++ 2008および2010でコンパイルすると、次のように生成されます。

animal.cpp(18) : error C2259: 'CPet' : cannot instantiate abstract class
    due to following members:
    'void IAnimal::isAlive(void)' : is abstract
    mytest.cpp(5) : see declaration of 'IAnimal::isAlive'

GCCは同様の警告を生成します。

animal.cpp: In function 'int main()':
animal.cpp:18:7: error: cannot declare variable 'cp' to be of abstract type 'CPet'
animal.cpp:14:8: note:   because the following virtual functions are pure within 'CPet':
animal.cpp:3:15: note:  virtual void IAnimal::isAlive()
于 2012-05-13T06:01:13.310 に答える