Consider the following example:
struct Grandpa {
Grandpa(int x) {}
};
struct Dad : Grandpa {
Dad(int y) : Grandpa(15) {}
};
struct Son : Dad {
Son(int z) : Dad(z) {}
};
int main () {
Son s(10);
}
It compiles just fine, however, if I make Grandpa not just baseclass of Dad, but virtual baseclass:
struct Grandpa {
Grandpa(int x) {}
};
struct Dad : virtual Grandpa {
Dad(int y) : Grandpa(15) {}
};
struct Son : Dad {
Son(int z) : Dad(z) {}
};
int main () {
Son s(10);
}
This code doesn't compile! Compilation fails with
example.cpp: In constructor ‘Son::Son(int)’:
example.cpp:12:27: error: no matching function for call to ‘Grandpa::Grandpa()’
12 | Son(int z) : Dad(z) {}
What are the rules, according to C++ standard, regarding virtual baseclasses' constructor calls?
As Pete Becker in comments, and Chris Dodd in answers have pointed out:
The closest thing that corresponds to this answer in C++ standard I found is: 15.6.2 Initializing bases and members # 13.1
What it says, is that order of which constructor is called is first virtual baseclasses (even non-direct baseclasses!!), and then direct non-virtual baseclassses. So compiler, after not seeing call to
Grandpaconstructor inSonconstructor, doesn't bother callingDadconstructor to find call toGrandpaconstructor there: compiler decides to fail compilation, which is OK for compiler, according to standard.