1

タイトルで問題を簡潔に説明するのに苦労したので、問題を理解し、より良いタイトルがある場合はお勧めします.

私の問題を可能な限り小さくしたバージョンを作成しました。その結果、すべての関数がインラインで定義されています。申し訳ありませんが、実際のコードはこのようではありません。

これは私の構造です:

class iobject
{
public:
    virtual bool isValid (void) = 0;
};

class object : virtual public iobject
{
public:
    object (void) { }
    virtual ~object () {}
    virtual bool isValid (void) { return true; }
};

上記のように、オブジェクトが有効かどうかを単純に追跡するインターフェイス + 実装...エンジン/システム内のすべてのオブジェクトがこの単一のオブジェクトから派生すると想像してください。

class ibase : public virtual iobject
{
public:
    virtual void show (void) = 0;
};

class base : public virtual object,
             public virtual ibase
{
public:
    base (int value) : object() { m_value = value; }
    virtual ~base () {}
    virtual void show (void) { std::cout << m_value << std::endl; }

private:
    int m_value;
};

これで、数値を格納して出力するだけの仮想クラスができました。オブジェクトから派生します。これで「ダイヤモンド」は完成です。

class derived1 : public virtual base
{
public: 
    derived1 (int value) : base (value) {}
    virtual ~derived1 () {}
};

ここで、基本クラスから派生します。この派生クラスについて注意すべきことは、基本クラス (int 値) と同じコンストラクター パラメーターがあることです。

class derived2 : public virtual derived1
{
public:
    derived2 (void) : derived1 (15) {}
    virtual ~derived2 () {}
};

最後に、この派生クラスから派生させます。ただし、このクラスにはコンストラクタ パラメータがないことに注意してください。代わりに、このクラスは、この例では値が 15 であることを内部的に認識している必要があります。

私が期待しているのは、派生 2 をインスタンス化すると、値 15 で派生 1 が構築され、オブジェクトを介して渡されることです。私は次のことをしたいと思います:

derived1 works(1234);
derived2 doesNotWork;

works.show();
doesNotWork.show();

しかし、これを試みると、次のようになります。

error C2512: 'base::base' : no appropriate default constructor available

空の base::base コンストラクターを追加すると、予想どおり m_value が未定義になります (ただし、とにかく試しました)。

明らかな何かが欠けているようです...、誰かがそれを強調できますか?

4

2 に答える 2

0

ダイヤモンドの継承はありません。ここには共有基本クラスはありません (派生 2 -> 派生 1 -> ベース -> (オブジェクト -> iobject)、ibase )。このチェーンのどこにも重複はありません。したがって、仮想継承は必要ないので、public virtual全面的に削除してください。これは不自然な例であり、実際の使用法と一致しないことは承知していますが、私の経験では、仮想呼び出しで実際に多重継承が必要になることは非常にまれです。 、ポインタの動作に関するオーバーヘッドと一般的な厄介さを呼び出します)。

于 2014-07-03T02:05:39.563 に答える