#include <stdio.h>
struct Base
{
virtual void thatSomething() = 0;
void doSomething() {thatSomething(); }
};
struct DerOne : Base
{
virtual void thatSomething() override {std::puts("DerOne"); }
};
struct DerTwo : Base
{
virtual void thatSomething() override {std::puts("DerTwo"); }
};
struct Joined : DerOne, DerTwo
{
Joined()
{
Base::doSomething();
}
};
int main()
{
Joined j;
return 0;
}
Output:
DerOne
Why is only thatSomething
of DerOne
called? I expect it to be called of both parent classes of Joined
.
@hvd mentioned that with multiple inheritance I have multiple instances of Base
.
Also worth mentioning: When I flip the inheritance of Joined
(struct Joined : DerTwo, DerOne
), I get
DerTwo
as output instead.
Only doing doSomething()
in the Joined
constructor will give me an error for ambiguity of the function call.
When I use virtual inheritance, I again get an ambiguity error.
If it is not possible to call both functions this way, what other options do I have in order to achieve that with only one line of code that does not address the intermediate classes in the hierarchy or even no line of code implicitly?
The quick fix is simply to have Joined call both, explicitly. (edited to override the virtual function)
virtual void Joined::thatSomething() override
{
DerOne::thatSomething();
DerTwo::thatSomething();
}
If that doesn't take care of everthing, then maybe inheritance isn't a good fit. Composition used to be used a lot more, before all the OOP, and it is still powerful.
If you're expecting a specific thing to happen when you call thatSomething(), but you don't know which one to call, then maybe it's simply not true that Joined is-a DerOne and is-a DerTwo. But it's much easier for Joined to have-a DerOne, and have-a DerTwo, and as many more as you want.
#include <list>
#include <memory>
struct DerHandler
{
std::list<std::unique_ptr<DerBase>> handlers;
void addHandler(DerBase *p) {
handlers.push_back(std::unique_ptr<DerBase>(p));
}
void doSomething() {
for (std::unique_ptr<DerBase> &rp : handlers)
rp->thatSomething();
}
};
struct Joined : DerHandler {
Joined(){
addHandler(new DerOne);
addHandler(new DerTwo);
}
};