Constructor selection with virtual inheritance
August 11th, 2009 § 3 Comments
Virtual inheritance has quite a few common pitfalls, one of which is related to the construction of the virtual base.
Consider the following code – what will eventually be printed?
#include <iostream>
using std::cout;
struct A {
A (int x=0) { cout << x; }
};
struct B : virtual A {
B () : A(1) {}
};
struct C : virtual A {
C () : A(2) {}
};
struct D : B, C {
};
int main () {
D d;
}
Hint: what class actually invokes A’s constructor?
D invokes A’s constructor directly when diamond-shaped hierarchy is present with a virtual base class. Constructor invocations of A from B and C are ignored when D is being instantiated. Try this.
struct D : B, C { D() : A(10) {} }; int main () { D d; B b; C c; }That is correct, thanks for posting!
To add to that, when virtual inheritance is involved, the compiler actually creates two constructors for the directly inheriting class: one that includes the call to A’s constructor (to be used when we create a regular object of class B) and one that doesn’t (used here).
Another very nice usage of the fact that the most derived class is the invoker of the virtual class’ constructor can be found here: http://www.research.att.com/~bs/bs_faq2.html#no-derivation