Reputation: 1564
#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?
Upvotes: 0
Views: 94
Reputation: 5871
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);
}
};
Upvotes: 1