In the common diamond scenario:
class MBase {
public:
MBase(int) {}
virtual char const* vf() const = 0;
virtual ~MBase() {}
};
class D1 : public MBase { //NOT VIRTUAL!!!
public:
D1() : MBase(1) {}
char const* vf() const { return "D1"; }
};
class D2 : virtual public MBase {
public:
D2() : MBase(2) {}
char const* vf() const { return "D2"; }
};
class Bottom : public D1, public D2 {
public:
char const* vf() const { return "Bottom"; }
}
What would change if I modified the inheritance modifier of Bottom to be virtual for both D1 and D2? I mean, would that make any impact:
class Bottom : public virtual D1, public virtual D2 {
public:
char const* vf() const { return "Bottom"; }
}
No it doesn’t. Each class chooses which of its direct base classes may be shared with others. Since
Bottomis a leaf in your implementation and it has in both cases only one instance ofD1andD2, it will in both cases have exactly one nested object of these types. SinceD1refuses to share anMBase,Bottomwill have twoMBaseobjects nested in it as well.However
MBaseis not directly accessible from both versions ofBottomsince it is ambiguous. You would have to explicitly cast toD1orD2in order to accessMBasethroughBottomobjects (precisely because there are twoMBases).The difference would be if you had one
D1that virtually inherits fromMBaseand one that doesn’t.