This question already has an answer here:
- Why must virtual base classes be constructed by the most derived class? 3 answers
The following code:
#include<iostream>
using namespace std;
class Man
{
int stories;
public:
Man(int stories) : stories(stories) {cout << "A man is created with " << stories << " stories." << endl;};
};
class Grandpa : public virtual Man
{
int pipes;
public:
Grandpa(int stories, int pipes) : Man(1000), pipes(pipes)
{
stories += stories;
cout << "Grandpa is created with " << stories << " stories and pipes." << endl;
};
};
class Father : public Grandpa
{
int cars;
public:
Father(int stories, int cars) : Man(1000), Grandpa(1000, 1), cars(cars)
{
stories += stories;
cout << "Father is created with " << stories << " stories and cars." << endl;
};
};
class Son : public Father
{
int girls;
public:
Son(int stories, int girls) : Man(1000), Father(1000, 3), girls(girls)
{
stories += stories;
cout << "Son is created with " << stories << " stories and girls." << endl;
};
};
int main()
{
Son Dick(1000, 5);
return 0;
}
Gives the following output on the run:
A man is created with 1000 stories.
Grandpa is created with 2000 stories and pipes.
Father is created with 2000 stories and cars.
Son is created with 2000 stories and girls.
And it does not compile, when I do not call Man(int) in Father's and Son's initializers' lists. It is trying to call Man(void), and Man() is not defined. Why is it so? Yet, I think, when Father's or Son's constructors were called, the virtual base's constructor had already been called in Grandpa! Moreover thus, I would expect the output to be:
A man is created with 1000 stories.
Grandpa is created with 2000 stories and pipes.
Father is created with 3000 stories and cars.
Son is created with 4000 stories and girls.
To recapitulate then: why a virtual base class constructor has to be called explicitly in an initializer list of a derived class, although it is already placed in an younger's ancestor initializer list? Why it is seemingly not called in the younger ancestor, and a default base class is tried to be called instead?
EDIT due to finding an answer to problem with numbers
What a shame :) I should have made int stories
in Grandpa protected int _stories;
and then the output would be as expected: 1000 stories for Man, 2000 for Grandpa, 3000 for Father and 4000 for Dick :) Otherwise stories += stories
acts on local variable instead of the Man's member... Sorry for bothering!