I have a diamond multiple inheritance scenario like this:
A
/ \
B C
\ /
D
The common parent, A, defines a virtual function fn().
Is it possible for both B and C to define fn()
?
If it is, then the next question is - can D access both B and C's fn() without disambiguation? I'm assuming there is some syntax for this..
And is it possible for D to do that without knowing specifically who are B and C? B and C can be replaces by some other classes and I want the code in D to be generic.
What I'm trying to do is to have D somehow enumerate all of the instances of fn() it has in its ancestry. Is this possible in some other means that virtual functions?
Unless you overwrite fn
again in D
, no it is not possible. Because there is no final overrider in a D object: Both C
and B
override A::fn
. You have several options:
C::fn
or B::fn
. Then, the one that still overrides A::fn
has the final overrider. A::fn
aswell as fn
in C
and B
. For example the following results in a compile time error:
#include <iostream>
class A {
public:
virtual void fn() { }
};
class B : public virtual A {
public:
virtual void fn() { }
};
class C : public virtual A {
public:
virtual void fn() { }
};
// does not override fn!!
class D : public B, public C {
public:
virtual void doit() {
B::fn();
C::fn();
}
};
int main(int argc, char **argv) {
D d;
d.doit();
return 0;
}
You can, however derive non-virtual from A in C and B, but then you have no diamond inheritance anymore. That is, each data-member in A appears twice in B and C because you have two A base-class sub-objects in an D object. I would recommend you to rethink that design. Try to eliminate double-objects like that that require virtual inheritance. It often cause such kind of conflicting situations.
A case very similar to this is when you want to override a specific function. Imagine you have a virtual function with the same name in B and C (now without a common base A). And in D you want to override each function but give different behavior to each. Depending whether you call the function with a B pointer or C pointer, you have the different behavior. Multiple Inheritance Part III by Herb Sutter describes a good way of doing that. It might help you decide on your design.