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 constructor of a virtual base class is called from the constructor of the most derived class, in this case, from the constructor of
Son
. Since there is no default constructor forGrandpa
, the constructor for Son needs to explicitly call theGrandpa
constructor.
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 Grandpa
constructor in Son
constructor, doesn't bother calling Dad
constructor to find call to Grandpa
constructor there: compiler decides to fail compilation, which is OK for compiler, according to standard.