Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have this 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 in main I can call it like this:

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

but I dont really like it.

Is there any other solution? Methods setId/getId from struct A are not needed in AB. I just did the inheritance, because I need foo() and other stuff from A, but all other methods are unique.

like image 268
Martin Perry Avatar asked Mar 11 '17 15:03

Martin Perry


People also ask

What is the common mistake in using multiple inheritance?

The error is due to the “Diamond Problem” of multiple inheritance. The Snake class does not know which breathe() method to call. In the first example, only the Animal class had overridden the breathe() method.

Is it possible to use multilevel and multiple inheritances simultaneously?

As shown above, we can derive a class from more than one class simultaneously. This way the derived class will acquire the features of all of its parent classes. This may give rise to serious ambiguities especially when the features inherited are the same. Note: Java does not support multiple inheritance using classes.

Why is multiple inheritance not a good idea?

Allowing multiple inheritance makes the rules about function overloads and virtual dispatch decidedly more tricky, as well as the language implementation around object layouts. These impact language designers/implementors quite a bit and raise the already high bar to get a language done, stable, and adopted.

When a function with the same name appears in more than one base class in multiple inheritance?

Inheritance Ambiguity in C++ In multiple inheritances, when one class is derived from two or more base classes then there may be a possibility that the base classes have functions with the same name, and the derived class may not have functions with that name as those of its base classes.


2 Answers

Since you said that you don't need A's version of those methods, you could write

struct AB : public A, public B
{
    void foo() override {}
    void foo2() override {}

    using B::setId;
    using B::getId;
};

This will put B's implementation of those methods into AB's namespace and make calling them unambiguous.

like image 158
Ben Steffan Avatar answered Sep 21 '22 09:09

Ben Steffan


I believe that both mine and the accepted answers introduces rather annoying problem, consider:

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

When the name hiding is used (accepted answer) the AB object never gets called while my answer (wrapping the call) does not account for this either. The correct approach in this case in my opinion is to use private inehritance of A and exposing only foo(), so only one thing would change from original OP's code:

struct AB : private A, public B
like image 37
Resurrection Avatar answered Sep 21 '22 09:09

Resurrection