2

I am developing an api for internal and external usage. On Visual Studio 10.

I have a virtual base class IA and a derived virtual base class IB. I implement IA with class A and then derive a concrete implementation for IB off of B. This to my understanding is the classic diamond problem. So I make A inheritance of IA virtual and the same for Bs inheritance of A. But I get a warning c4250 (warning C4250: 'B' : inherits 'A::A::AnInt' via dominance)

  • while this warning seams to indicate the compiler is doing what I want I was uncomfortable with the warning and wanted to make sure it was safe to #pragma out, or there some issue I am not aware of.

The code

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; 
    }   
};

Second part of the question. If you are creating an api where the consuming developers will not be able to change the abstract classes in question. Should you avoid designing interfaces with inheritance or go ahead and make the derived classes utilize virtual inheritance.

curiousguy
  • 8,038
  • 2
  • 40
  • 58
rerun
  • 25,014
  • 6
  • 48
  • 78

2 Answers2

1

This problem has been discussed previously. Dani van der Meer's answer specifically addresses this issue. It's been filed as a won't fix bug report in Visual Studio since 2005.

If you're not a fan of disabling warnings, you could always make the function selection explicit.

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

    int AnInt2()
    {
        return 4; 
    }   
};
Community
  • 1
  • 1
Roger Hanna
  • 176
  • 8
0

I have a similar problem.
I am using MSVC2010

I ended up create a separate file specifying the delegation (since this will be common for all derived) to overcome the warnings Any comments on it this is bad or not is appreciated

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"
}

content of "CommonImpl.delegate"

virtual void Foo() overload {return CommonImpl::Foo();}