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

徘徊边缘 提交于 2020-01-23 07:22:42

问题


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.


回答1:


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.




回答2:


What about wrapper forwarding methods:

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

That way you do not become "victim" of name hiding, your intent becomes clear in the code and you have the names that reflect what they do and you do not need to access the member(s) of base class(es) explicitely.

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




回答3:


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



回答4:


Typically with OO and Inheritance, if functionality reuse is unknown at the time, it is typically better to implement the function several times until you determine a pattern that will allow you to break it apart.

For instance, there is nothing wrong with having a class object being a container of data and inherriting from it.

class IdentificationData {
    int ID;
    . . .
}

You also do not necessarily need to have functions be part of a class. A class is simply a container, and is used to organize and encapsulate data, functions that may operate on the data, or a collection of functions into one common set.

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

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

class AB: IdentificationData, B {
    . . .
}

AB* ab = new AB();
IdentificationFunctionality::SetID(&ab);

The other benefits to this, is this will allow you to do some book keeping without your objects needing to know the details of the data-banking system.



来源:https://stackoverflow.com/questions/42736889/c-multiple-inheritance-same-method-names-can-i-somehow-remove-one-of-them

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!