2

内部および外部で使用するためのAPIを開発しています。VisualStudio10の場合。

仮想基本クラスIAと派生仮想基本クラスIBがあります。私はクラスAでIAを実装し、次にBからIBの具体的な実装を導き出します。これは私の理解では古典的なダイヤモンド問題です。したがって、IAの継承を仮想にし、AのBの継承についても同じにします。しかし、警告c4250が表示されます。(warning C4250: 'B' : inherits 'A::A::AnInt' via dominance)

  • この警告は、コンパイラが私が望むことを実行していることを示すために継ぎ目がありますが、警告に不快感を覚え、#pragmaを安全に実行できることを確認したかったのですが、気づいていない問題がありました。

コード

class IA
{
public:
    virtual int AnInt() = 0; 
};

class A : virtual public IA 
{
public:
    virtual int AnInt()
    {
        return 3; 
    }
};

class IB : virtual  public IA
{
public:
    virtual int AnInt2() = 0; 
};

class B : public A, public IB
{
public:
    int AnInt2()
    {
        return 4; 
    }   
};

質問の2番目の部分。消費する開発者が問題の抽象クラスを変更できないAPIを作成している場合。継承を使用したインターフェイスの設計を回避するか、先に進んで派生クラスに仮想継承を利用させる必要があります。

4

2 に答える 2

1

この問題は以前に説明されてます。Dani van der Meerの回答は、特にこの問題に対処しています。2005年以降、VisualStudioで修正されないバグレポートとして提出されています。

警告を無効にするのが好きでない場合は、いつでも関数の選択を明示的にすることができます。

class B : public IB, public A
{
public:
+    int AnInt()
+    {
+        return A::AnInt();
+    }

    int AnInt2()
    {
        return 4; 
    }   
};
于 2012-03-18T22:41:09.073 に答える
0

私も同様の問題を抱えています。
MSVC2010を使用しています

警告を克服するために、委任を指定する別のファイルを作成することになりました(これはすべての派生ファイルに共通であるため)これに関するコメントは悪いかどうかはありません

class iCommon //pure virtual
{
 virtual void Foo()=0;
}

class iDerived: virtual iCommon //pure virtual... intended to allow testing with mocks
{
 virtual void Bar()=0;
}

class CommonImpl : virtual public iCommon
{
 virtual void Foo(){/* do common stuff*/}
}

class Derived: virtual public CommonImpl,virtual public iDerived
{
  //implement the derived functionality
  virtual void Bar(){/* this method is not common*/}
 //now load the file to avoid compiler warnings
  #include "CommonImpl.delegate"
}

「CommonImpl.delegate」の内容

virtual void Foo() overload {return CommonImpl::Foo();}
于 2015-01-03T14:43:33.717 に答える