Multiple inheritance with abstract and defined inherited functions with the same name

First of all, I apologize if there is another publication that answers this, all similar entries that I found related to diamond inheritance schemes or certain functions, which is not there.

In short, I wonder if it is possible to inherit one class from two other classes, where both child classes have a function with the same name and arguments, but it is defined in one child class and pure-virtual in another. Also, if I can do this, will call a function in a pure-virtual / abstract class end up calling a specific function on another 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 completed with errors that say:

'AB': it is not possible to instantiate an abstract class for the following members: 'void A :: Set (int)': abstract

When I conducted my own research, I could not find a clear answer, but, based on other questions that related to topics, I found that using this “use of B :: Set” in class AB can help with this. But when I try to add it to the AB class definition, the error persists.

Is there any way to do this?

+4
source share
3 answers

Have you tried to implement the method:

 class AB : public A, public B { void Set(int X) {} }; 

The reason it doesn't work is because A::Set() is purely virtual. That is, it has no implementation. But you are trying to call it. You must override it in a derived class in order to be able to create derived classes.

using does not work in your case because you have A* , so there is no ambiguity for the compiler.

If you have:

 AB* ObjectA = new AB(); ObjectA->Set(Y); 

you will need to use using inside the AB declaration to eliminate the ambiguity.

0
source

If you had 2 normal Set functions in A and B , then using B::Set will tell the compiler that if you have an object of class AB and the method of calling Set this object, B::Set will be called if AB::Set not defined explicitly.

Your situation is different. You have a pure virtual function A::Set , which leads A to an abstract class. Since AB does not override A::Set , AB also becomes abstract, so you cannot create it.

What can you 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 using the same method names for base classes, since I do not recommend multiple inheritance, try using aggregation instead.

+2
source

The class AB comes from A, A has a pure virtual method making an abstract category, AB must implement any pure virtual methods declared in the base class in order to be instantiated.

I would try to avoid multiple inheritance, this can cause a lot of headaches, and, as a rule, there are more effective ways to solve the problem, for example, in this example I do not understand the point of getting both from A and B, if B shares and actually implements the same interface as A, then B must be obtained from A.

0
source

Source: https://habr.com/ru/post/1396056/


All Articles