I'm a bit confused about how virtual base classes work. In particular, I was wondering how the constructor of the base class gets called. I wrote an example to understand it:
#include <cstdio>
#include <string>
using std::string;
struct A{
string s;
A() {}
A(string t): s(t) {}
};
struct B: virtual public A{
B(): A("B"){}
};
struct C: virtual public A {};
struct D: public B, public C {};
struct E: public C, public B {};
struct F: public B {};
int main(){
D d;
printf("\"%s\"\n",d.s.c_str());
E e;
printf("\"%s\"\n",e.s.c_str());
F f;
printf("\"%s\"\n",f.s.c_str());
B b;
printf("\"%s\"\n",b.s.c_str());
}
Which outputs
""
""
""
"B"
I wasn't sure what would happen in the first two cases, but for the third one at least I was expecting the output to be "B". So now I'm just confused. What are the rules for understanding how the constructor of A gets called?
There is always just one constructor call, and always of the actual, concrete class that you instantiate. It is your responsibility to endow each derived class with a constructor which calls the base classes' constructors if and as necessary, as you did in B
's constructor.
Update: Sorry for missing your main point! Thanks to ildjarn.
However, your B
inherits virtually from A
. According to the standard (10.1.4 in the FIDS), "for each distinct baseclass that is specified virtual, the most derived object shall contain a single base class subobject of that type". In your case this means that when constructing the base, your class F
immediately calls A
's default constructor, not B
's.