First off I apologize if there is another post out there that answers this, all the similar posts I found dealt with diamond inheritance schemes or defined functions, which this does not.
In short, I'm wondering if it is possible to have one class inherit from two other classes where both child classes has a function with the same name and arguments but it is defined in one child class, and pure-virtual in another. Furthermore if I can do this, would invoking the function on the pure-virtual/abstract class end up calling the defined function on the other child class with minimal changes to the derived class?
Example:
class A
{
public:
virtual void Set(int X) = 0;
};
class B
{
public:
virtual void Set(int X);
};
class AB : public A, public B
{
//other methods not relevant to example go here
};
int main(int argc, char **argv)
{
int Y = 5;
A* ObjectA = new AB();
ObjectA->Set(Y);
return 0;
}
So far my attempts to compile this basic example have been met with errors that say:
'AB' : cannot instantiate abstract class
due to following members:
'void A::Set(int)' : is abstract
When doing my own research I couldn't find a clear answer, but based on other questions that dealt with related topics I found that using a "using B::Set" in class AB may help with this. But when I try adding it to the AB class definition, the error persists.
Is there any way I can make this work?
Have you tried implementing the method:
class AB : public A, public B
{
void Set(int X) {}
};
The reason it's not working is that A::Set()
is pure virtual. I.e. it has no implementation. But you try to call it. You have to override it in the derived class in order to be able to instantiate the derived class.
The using
doesn't work in your case because you have an A*
, so there's no ambiguity for the compiler.
In case you had:
AB* ObjectA = new AB();
ObjectA->Set(Y);
you'd have to use using
inside the declaration of AB
to resolve the ambiguity.
If you had 2 normal functions Set
in A
and B
, then using B::Set
would tell the compiler that if you have object of class AB
and call method Set
of that object, B::Set
will be invoked, if AB::Set
not defined explicitly.
Your situation is different. You have pure virtual function A::Set
that leads A
to be abstract class. As AB
does not override A::Set
, AB
becomes abstract too, that is why you cannot instantiate it.
What you can do here
You can implement AB::set
to call B::Set
:
class AB : public A, public B
{
public:
void Set(int x) { return B::Set(x); }
};
Also I do not recommend same method names for base classes, as I do not recommend multiple inheritance, try use aggregation instead.
Class AB derives from A, A has a pure virtual method making the class abstract, AB must implement any pure virtual methods declared in a base class in order to be instantiated.
I would try to avoid multiple inheritance it can cause many headaches and there are generally better ways to solve a problem, for instance in this example I don't understand the point in deriving from both A and B, if B shares and in fact implements the same interface as A then surely B should be derived from A.