3

私はこれを持っています

    A
  /   \
 B     C
  \   /
    D

Aには純粋仮想関数があり、次のようにプロトタイプ化されています。

virtual A* clone(void) const = 0;

BとCは実質的にAから継承します(class B: public virtual Aclass C: public virtual A

Bには、次のようにプロトタイプ化された仮想関数があります。

virtual B* clone(void) const {}; 

Cには、次のようにプロトタイプ化された仮想関数があります。

virtual C* clone(void) const {};

Dは、次のようにBとCの両方から継承しますclass D: public B, public C 。Dには、次のようにプロトタイプ化された仮想関数があります。

virtual D* clone(void) const {};

さて、コンパイルすると、次の6行のエラーが発生します。

error C2250: 'D' : ambiguous inheritance of 'B *A::clone(void) const'

この問題を解決する方法についてはおかしな考えはありません。

前もって感謝します。

4

3 に答える 3

9

階層内に親のコピーが1つだけ必要な場合は、仮想継承を使用します。

class B : public virtual A

編集:
MSVC ++ 2010にバグがある可能性があります。Intellisenseは問題を検出しませんが、コンパイラは問題をチョークします。VC6はそれに十分満足しているので奇妙です。

回避策として、次のようにDを宣言すると、MSVC ++ 2010が幸せになり、この問題が発生することなくコンパイラーでも動作します。

class D: public virtual A, public B, public C
于 2010-08-28T22:07:14.717 に答える
5

元の投稿で説明したことは完全に合法です。これを正確に実行するクイックサンプルコードは、ComeauOnlineコンパイラによってエラーなしでコンパイルされます

class A {
public: virtual A* clone() const = 0;
};

class B: public virtual A {
public: virtual B* clone() const { return 0; }
};

class C: public virtual A {
public: virtual C* clone() const { return 0; }
};

class D: public B, public C
{
public: virtual D* clone() const { return 0; }
};

あなたがしていると言ったことをしていないか、あなたのコンパイラが壊れています。コンパイルしようとしている実際のコードを投稿してください。

PS VS 2010 Expressでこれをコンパイルしようとしたところ、同じエラーが発生しました。Gunslinger47もコメントで示唆しているように、これはVS2010コンパイラのバグです。

于 2010-08-28T22:37:41.577 に答える
1

ダイヤモンドの継承を避けますか?;->

とにかく、ここにサンプルがあります(本当にサンプル-そのようにキャストしないでください)

// ConsoleCppTest.cpp:コンソールアプリケーションのエントリポイントを定義します。//

#include "stdafx.h"
#include "iostream"

class A {
public:
    virtual void* clone() = 0;
};

class B: public A {
public:
    virtual void* clone() = 0;
};

class C: public A {
    public:
    virtual void* clone() = 0;
};

class D: public B, public C
{
public:


    virtual void* B::clone() 
    {
        std::cout << "B";
        return (void*)this;
    }

    virtual void* C::clone()
    {
        std::cout << "C";
        return (void*)this;
    }
};

int _tmain(int argc, _TCHAR* argv[])
{

    D* d = new D();

    void* b = ((B*)d)->clone();

    void* c = ((C*)d)->clone();

    return 0;
}
于 2010-08-28T22:10:41.120 に答える