Is it possible to implement an abstract base class with members inherited from another parent class in C++?
It works in C#, so I tried doing it in C++:
// Virtual destructors omitted for brevity
class ITalk
{
public:
virtual void SayHi() = 0;
};
class Parent
{
public:
void SayHi();
};
class Child : public Parent, public ITalk
{
};
void Parent::SayHi()
{
std::printf("Hi\n");
}
My compiler didn't really like it though:
ITalk* lChild = new Child(); // You idiot, Child is an abstract class!
lChild->SayHi();
I can't add public ITalk
to the Parent
class because "base-class 'ITalk' is already a base-class of 'Parent'." I could move public ITalk
up to the Parent
class, but in my particular scenario that complicates a lot of things.
No because what you really have is two base classes without any knowledge of each other.
If Parent and Italk had two variables named i, there'd be two instances of "i", ITalk::i and Parent::i. To access them you'd have to fully qualify which one you wanted.
The same is true of methods, lChild has two methods called SayHi and you need to clarify which one you mean when calling SayHi because the multiple inheritance has made it ambiguous.
You have Parent's SayHi
and Italk's SayHi:
The latter is pure virtual and because its abstract needs to be overridden locally in Child. To satisfy this you'll need to define
Which would now hide Parent::SayHi() when invoking SayHi without scoping it to the class:
Of course Child::SayHi() could call Parent::SayHi():
which would solve your problem.
It is impossible to be done as you wrote it. The reason behind it is, that every non-static method needs object (
this
) to operate on (here you don't use any of the object's fields or methods, but that doesn't matter), and this object must be of apropriate type.Parent::sayHi
expectsthis
to be of the typeParent
, and sinceITalk
is not related toParent
at all,Parent::sayHi
andITalk::sayHi
methods are fundamentaly incompatible.C++ is having static type system, so the type must be known at compile time. Languages that use dynamic typing are usually less strict about such constructions, as they can test if object is of apropriate class at function call.
In C++ the easiest way to implement such behavior would be to simply make
Child::sayHi
to callParent::sayHi
, as Child is the only class that "knows" where areParent
andITalk
and how should they be related.Try to use virtual inheritance
ITalk
contains the pure virtual functionSayHi()
, so if you want to be able to instantiate a class that derives fromITalk
that class must implementSayHi()
.Alternatively,
Parent
can inherit fromITalk
(but notChild
) and the code you've posted will work.Also, when implementing a base class with virtual functions you must define virtual destructors for those base classes. So ITalk should be:
If you don't do that the following produces undefined behavior