4

単語の説明(以下のコード): クラスのコレクションを提供するライブラリがあります。クラスの各グループには、( ClassA_PartialClassA)、( ClassB_PartialClassB) などの 2 つの具象型があります。これらはそれぞれ ( Interface_PartialInterface) を実装します。さらに、Interface is a Interface_Partialおよび each Class? is a Class?_Partial - は、トップが仮想的に継承されるダイヤモンド継承パターンを作成します。

と の両方をInterface_Partial継承すると関数があいまいになるのはなぜですか?ClassAClassB

struct Interface_Partial
{ 
    virtual ~Interface_Partial(); 
    virtual void f() = 0;
};

struct Interface
    :
    virtual Interface_Partial
{
    virtual void g() = 0;
};


struct ClassA_Partial : public virtual Interface_Partial
{
    void f() {};
};


struct ClassA : public Interface, public virtual ClassA_Partial
{
    void g() {};
};

struct ClassB_Partial : public virtual Interface_Partial
{
    void f() {};
};


struct ClassB : public Interface, public virtual ClassB_Partial
{
    void g() {};
};

struct MyClass : public ClassA, public ClassB
{ }; // error C2250: MyClass : ambiguous inheritance of 'void Interface_Partial::f(void)'

共通のインターフェースを複数回継承する場合、通常の方法で曖昧さを解消できないのはなぜですか? 例えば

struct ClassX : public Interface_Partial { void f() {} };
struct ClassY : public Interface_Partial { void f() {} };
class Another : public ClassX, public ClassY
{};

void func()
{
    // This is ok
    Another a;
    a.ClassX::f();   

    // Why would this not work?
    // unambiguously refers to the one and only f() function 
    // inherited via  ClassA
    MyClass b;
    b.ClassA::f();   
}
4

2 に答える 2

2

仮想継承のため、基本クラス Interface_Partial の vtable は 1 つだけです。仮想継承を使用すると、「仮想性」がすべてのレベルのすべての派生クラスに感染します。

1 つは から、もう 1MyClassつは からの 2 つの異なるバージョンの f() が利用可能であるため、継承はあいまいです。の仮想継承により、同じレベルにある 2 つの派生クラスの実装があり、同じ仮想関数をオーバーライドしようとしています。仮想基本クラスを宣言すると、すべての派生クラスがその vtable を含む仮想基本クラスを共有します。共有 vtable は、呼び出される必要がある仮想関数のポインターを含むように更新されます。しかし、同じように「良い」ものを 2 つ選択できるため、どちらか一方を選択する方法はありません。ClassAClassBInterface_Partial

あなたが与える他の例では、Interface_Partialは と の非仮想基本クラスでClassXあるClassYため、各クラスは完全に異なる仮想関数をオーバーライドしています。これはコンパイラにとって明白ですが、それらを呼び出すときは、呼び出す特定のものを指定する必要がありf()ます。

f()これは、 in の実装を提供することで解決できますMyClass

于 2015-02-17T08:12:43.910 に答える