Hierarchical Interfaces and Implementations

The following code only works if you uncomment the line

virtual void FuncA() { ImplA::FuncA(); } 

in the ImplB class, otherwise I get a compiler error:

cannot create an instance of an abstract class ... FuncA (void) ': abstract

Question: why doesn’t it get the implementation for FuncA() from the inherited ImplA ?

 class InterfaceA { public: virtual void FuncA()=0; }; class InterfaceB : public InterfaceA { public: virtual void FuncB()=0; }; class ImplA : public InterfaceA { public: virtual void FuncA() { printf("FuncA()\n"); } }; class ImplB : public ImplA, public InterfaceB { public: // virtual void FuncA() { ImplA::FuncA(); } virtual void FuncB() { printf("FuncB()\n"); } }; { ImplB *b = new ImplB(); InterfaceA *A= b; A->FuncA(); InterfaceB *B= b; B->FuncB(); B->FuncA(); } 
+7
c ++ inheritance abstract-class
source share
2 answers

You have come across a copy of the “diamonds” problem with multiple inheritance. You will need to use "virtual" inheritance (which is equivalent to adding the virtual keyword when inheriting)

The problem is that ImplB has two paths to the base class InterfaceA. However, your intention is that interfaces do not provide any implementation. So you need to point this to the compiler so that it can unify pure virtual functions.

For a better explanation: http://www.cprogramming.com/tutorial/virtual_inheritance.html

I changed your code to add virtual when you inherit from interfaces. Now it compiles even if the line is commented out. Also note: I think you are missing virtual destructors, so you will have other problems. This code compiles without uncommenting FuncA.

 #include <cstdio> class InterfaceA { public: virtual void FuncA()=0; }; class InterfaceB : public virtual InterfaceA { public: virtual void FuncB()=0; }; class ImplA : public virtual InterfaceA { public: virtual void FuncA() { printf("FuncA()\n"); } }; class ImplB : public ImplA, public virtual InterfaceB { public: // virtual void FuncA() { ImplA::FuncA(); } virtual void FuncB() { printf("FuncB()\n"); } }; int main() { ImplB *b = new ImplB(); InterfaceA *A= b; A->FuncA(); InterfaceB *B= b; B->FuncB(); B->FuncA(); } 
+3
source share

Multiple inheritance is not "mixins"

You can inherit from several classes that have methods with the same name, but that does not make them the same.

A thing that inherits from a virtual class must implement the pure virtual functions of its parents.

If the method names were not limited, you could get combinations of parent classes that would be mutually exclusive for inheritance, because method implementations with a common name would not be compatible.

I am a little surprised that the placement using ImplA::FuncA; ImplB doesn't solve it: https://gcc.godbolt.org/

0
source share

All Articles