4

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.

5
  • You're getting an ambiguous reference as it doesn't know whether to use class A or imp_A. To get around this you will need to prefix it with the base class you're wanting to implement it from so if you wanted to use class A then you would put A::FA. You cannot instantiate virtual methods but you can ovverride them so you would need to specify that you're overriding the method. I haven't used C# in a while so I can't remember the exact syntax (hence why I'm commenting rather than answering). Commented Mar 1, 2016 at 13:31
  • @Vistari This is c++ and not c#. As FA is implemented in Imp_A, why I can not instantiate Imp_B? Commented Mar 1, 2016 at 13:35
  • @mtk99 This is not a duplicate of that question since here imp_A is based on A and on that question implementation has no relation to virtual class. Commented Mar 1, 2016 at 13:52
  • You are right, sorry Commented Mar 1, 2016 at 13:54
  • The actual error is that the call FA(); is ambiguous (cannot decide between A::FA that came via B, and A::FA that came via Imp_A). "Imp_B is virtual and can not be instantiated" is a cascade that should be ignored (it happened because the failure of FA(); to compile means that FB() { .... } did not compile, so the class was not considered to have overriden the pure virtual definition) Commented Mar 1, 2016 at 14:03

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

9 Comments

Thanks, this did not solve the problem: Do you mean virtual public imp_A? Even this did not solved the problem. I am still getting the same error.
well, I compiled it here: cpp.sh and it compiles fine; mind that you have a typo in your original code FB() needs a return type.
I think you also need class Imp_A: virtual public A, and class Imp_B: public Imp_A. Basically, everything that inherits A needs to inherit it virtually.
@Pandrei Can you please share your code on cpp.sh, so I can check it with my implementation?
@MartinBonner; not you don't Imp_A is not used in multiple inheritence and Imp_B does not need to inherit from imp_A it already has two class A definitions from A and B
|
2

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
    ...
    

3 Comments

another solution is to explicitly indicate Imp_A::FA() (or B::FA(), if that one had a body)
@M.M: You are right for the part of calling FA in FB, but that would not solve the problem that Imp_B would still be abstract until it explicitely overrides B::FB
Not sure what you are talking about, void FB() in Imp_B overrides virtual void FB() = 0; in B
1
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.

1 Comment

sorry, it was the type mistake in code, the original code that I have has void both on implementation and interface.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.