C++ multiple inheritance - same method names - can I somehow remove one of them?
The accepted answer does work as long as you call setId(int)
on an object of type AB or an AB pointer (most cases, surely). But if you want to call the function on A* ab = new AB();
you have to explicitly override it.
struct A {
int idA;
virtual void setId(int i) { idA = i;}
};
struct B {
int idB;
virtual void setId(int i) { idB = i;}
};
struct AB : public A, public B
{
void setId(int i) override { B::setId(i); }
};
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.
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
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.