Implementing elements of an abstract class in a parent class

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 to do this 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 really didn't like it:

 ITalk* lChild = new Child(); // You idiot, Child is an abstract class! lChild->SayHi(); 

I cannot add public ITalk to the Parent class because the โ€œbase classโ€œ ITalk โ€is already the base classโ€œ Parent. โ€I could move public ITalk to the Parent class, but in my specific scenario, which complicates many things.

+3
c ++ inheritance abstract-class
source share
4 answers

No, because you really have two base classes that don't know each other.

 Italk parent
  / \ / \
   |  |
   + --------- +
        |
      Child

If Parent and Italk had two variables named i, there would be two instances of "i", ITalk :: i and Parent :: i. In order to access them, you will need to fully determine which one you need.

The same goes for methods, lChild has two methods called SayHi, and you need to figure out which one you have in mind when calling SayHi, since multiple inheritance makes it ambiguous.

Do you have parent SayHi

 lChild->Parent::SayHi(); 

and Italk SayHi:

 lChild->ITalk::SayHi(); 

The latter is pure virtual and because its abstraction must be redefined locally in Child. To satisfy this, you need to define

 Child::SayHi(); 

What Parent :: SayHi () now hides when SayHi is called without looking at its class:

 lChild->SayHi() //parent now hidden, invoke child's 

Of course Child :: SayHi () can call Parent :: SayHi ():

 void Child::SayHi() { Parent::SayHi(); } 

which will help solve your problem.

+4
source share

ITalk contains the pure virtual function SayHi() , so if you want to be able to instantiate a class derived from ITalk , this class must implement SayHi() .

 class Child : public Parent, public ITalk { public: void SayHi() { std::cout << "Hi!" << std::endl; } }; 

Alternatively, Parent can inherit from ITalk (but not Child ), and the code you posted will work.

In addition, when implementing a base class with virtual functions, you must define virtual destructors for these base classes. Therefore, ITalk should be:

 class ITalk { public: virtual void SayHi() = 0; virtual ~ITalk() {} }; 

If you do not, you will get undefined behavior

 ITalk* lChild = new Child(); lChild->SayHi(); delete lChild; 
+1
source share

It is impossible to do as you wrote it. The reason is that for every non-static method an object ( this ) is required to work (here you do not use any of the fields or methods of the object, but it does not matter), and this object must be of the appropriate type. Parent::sayHi expects this to be of type Parent , and since ITalk is not associated with Parent , the methods Parent::sayHi and ITalk::sayHi fundamentally incompatible.

C ++ has a static type system, so the type must be known at compile time. Languages โ€‹โ€‹that use dynamic typing are usually less strict with respect to such constructs, since they can check if an object is a suitable class when calling a function.

In C ++, the easiest way to implement this behavior would be to simply make Child::sayHi to call Parent::sayHi , since Child is the only class that โ€œknowsโ€ where Parent and ITalk are and how they should be related .

 class Child : public Parent, public ITalk { virtual void sayHi(){ Parent::sayHi(); } }; 
+1
source share

Try using virtual inheritance

 class ITalk { public: virtual void SayHi() = 0; }; class Parent: virtual ITalk { public: void SayHi(); }; class Child : public Parent, public virtual ITalk { }; void Parent::SayHi() { std::printf("Hi\n"); } 
0
source share

All Articles