C ++ multiple inheritance - same method names - can I somehow remove one of them?

I have these structures in C ++ 11

struct A { int idA; void setId(int i) { idA = i;} int getId() { return idA;} virtual void foo() = 0; }; struct B { int idB; void setId(int i) { idB = i;} int getId() { return idB;} virtual void foo2() = 0; }; struct AB : public A, public B { void foo() override {} void foo2() override {} }; 

Now basically I can call it like this:

 AB * ab = new AB(); ab->B::setId(10); 

but I really don't like it.

Is there any other solution? The setId/getId from struct A methods are not needed in AB . I just inherited because I need foo() and other things from A , but all other methods are unique.

+5
source share
4 answers

Since you said that you do not need A version of these methods, you can write

 struct AB : public A, public B { void foo() override {} void foo2() override {} using B::setId; using B::getId; }; 

This will put B implementation of these methods in the AB namespace and make them unique.

+5
source

How about label forwarding methods:

 struct AB : public A, public B { public: void setAId(int i) { A::setID(i); } void setBId(int i) { B::setID(i); } }; 

Thus, you do not become a β€œvictim” of name hiding, your intentions become clear in the code, and you have names that reflect what they do, and you do not need access to the elements of the base class (es)) explicitly.

Alternatively, you can create another base class and inherit it in almost both A and B , in which you would specify the setId method.

+2
source

I believe that both my and accepted answers introduce a rather unpleasant problem, consider:

 AB ab; A *a = &ab; a->setId(10); //problem a->foo(); //calls AB::foo() correctly 

When name hiding (accepted answer) is used, the AB object is never called, while my answer (ending the call) does not take this into account. The correct approach in this case, in my opinion, is to use private inehritance A and expose only foo() , so only one can change from the OP source code:

 struct AB : private A, public B 
+1
source

Usually with OO and Inheritance, if reusing a function at that time is not known, it is usually best to implement this function several times until you define a template that allows you to break it down.

For example, there is nothing wrong with the fact that a class object is a data container and inherits from it.

 class IdentificationData { int ID; . . . } 

In addition, it is not necessary that the functions be part of the class. A class is just a container and is used to organize and encapsulate data, functions that can work with data, or a set of functions in one common set.

 class IdentificationFunctionality{ static SetID( IdentificationData* obj) {...} } 

Doing this will allow you to do something like ...

 class AB: IdentificationData, B { . . . } AB* ab = new AB(); IdentificationFunctionality::SetID(&ab); 

Other advantages of this is that it allows you to make some books without your objects, which should know the details of the banking data processing system.

0
source

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


All Articles