views:

159

answers:

3

I have the following class structure:

class InterfaceA
{ 
   virtual void methodA =0;
}

class ClassA : public InterfaceA
{
   void methodA();
}

class InterfaceB : public InterfaceA
{
   virtual void methodB =0;
}

class ClassAB : public ClassA, public InterfaceB
{ 
   void methodB(); 
}

Now the following code is not compilable:

int main()
{
    InterfaceB* test = new ClassAB();
    test->methodA();
}

The compiler says that the method methodA() is virtual and not implemented. I thought that it is implemented in ClassA (which implements the InterfaceA). Does anyone know where my fault is?

+2  A: 

This problem exists because C++ doesn't really have interfaces, only pure virtual classes with multiple inheritance. The compiler doesn't know where to find the implementation of methodA() because it is implemented by a different base class of ClassAB. You can get around this by implementing methodA() in ClassAB() to call the base implementation:

class ClassAB : public ClassA, public InterfaceB
{ 
    void methodA()
    {
        ClassA::methodA();
    }

    void methodB(); 
}
Andy
If C++'s rules are similar to Java's, the compiler still wouldn't know about it because the pointer was declared as `InterfaceB`, which has no `methodA`.
Michael Myers
mmyers: That's wrong for both C++ and Java. InterfaceB inherits from InterfaceA where methodA is defined.
jmucchiello
InterfaceB inherits from interfaceA so it should have methodA
stonemetal
Oops, I totally read that code wrong.
Michael Myers
The above solution was my first approach to solve the issue. It worked, but it was very bad to handle. (If the Interface A changes, I had to do the changes in every inherited class too)
MOnsDaR
+11  A: 

That is because you have two copies of InterfaceA. See this for a bigger explanation: http://www.parashift.com/c++-faq-lite/multiple-inheritance.html (your situation is similar to 'the dreaded diamond').

You need to add the keyword virtual when you inherit ClassA from InterfaceA. You also need to add virtual when you inherit InterfaceB from InterfaceA.

laura
Thanks for the clarification laura.
Seth Illgard
A: 

You have a dreaded diamond here. InterfaceB and ClassA must virtually inherit from InterfaceA Otherwise you ClassAB has two copies of MethodA one of which is still pure virtual. You should not be able to instantiate this class. And even if you were - compiler would not be able to decide which MethodA to call.

BostonLogan