mans
mans

Reputation: 18148

Multiple inheritance in c++ with virtual functions

I have this code:

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

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

class Imp_A: public A
{
public:
   void FA()
   {
      // implement FA
   }
};

class Imp_B :public Imp_A, public B
{
   public:
       void FB()
       {
           // implement FB by calling FA()
           FA();
           // do some more work here.
        }
};

in class Imp_B, I don't want to implement FA as it is already implemented in Imp_A which this class is based.

But when I try to compile my code, I am getting error that Imp_B is virtual and can not be instantiated.

also when I try to call FA inside FB, I am getting error that FA is ambiguous.

How can I solve this problem?

Please note that Imp_A is based on A and implement it, Imp_B is based on Imp_A and B and the idea is that it uses implementation of A from imp_A and only implement B.

Upvotes: 4

Views: 1724

Answers (3)

Serge Ballesta
Serge Ballesta

Reputation: 148870

Your inheritance shema is more or less:

   Imp_B
   /   \
Imp_A   B
  |     |
  A     A

That means that you inherit from two different implementations of A. So Imp_A::FA is indeed defined but B::A is not, so the class Imp_B is still abstract. And it also explains the error that FA is ambiguous, because it could be either Imp_A::FA or B::A.

Ways to solve it:

  • you could remove the inheritance class B: public A. That way A and FA will only exist in one branch and all will be defined
  • you could make base class A virtual, meaning that only one instance will exist in Imp_B:

    class B: virtual public A
    ...
    class Imp_A: virtual public A
    ...
    

Upvotes: 2

Pandrei
Pandrei

Reputation: 4951

This looks like the classic "diamond inheritance problem" where you have a virtual method defined in a base class which is inherited by two or more other classes which are used as source for multiple inheritance.

Anyway - virtual inheritance is the answer to your problem

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

class B: virtual public A
{
public:
    virtual void FB()=0; //probably a pure virtual function as well!?
}

class Imp_A: virtual public A
{
public:
   void FA()
   {
      // implement FA
   }
}

class Imp_B :public Imp_A, public B //since you call FA() you need it's implementation from Imp_A
{
   public:
       void FB()
       {
           // implement FB by calling FA()
           FA();
           // do some more work here.
        }
}

The problem here is that Imp_b ends up with to definition for FA coming from two class A definitions; using virtual inheritance helps solve this issue.

Upvotes: 2

Sam Varshavchik
Sam Varshavchik

Reputation: 118292

class B: public A
{
public:
    virtual FB()=0;
}

You forgot to explicitly declare this as void, so this declares:

virtual int FB()=0;

And in Imp_B you declare:

void FB();

That doesn't work, of course. You didn't override anything there.

Upvotes: 1

Related Questions