Reputation: 390
Let's say I have a base class A and class B derives from it. Class C from B and so on ..... Y from Z.
Who will be responsible for initializing the data members of class A, when I instantiate class Z?
Upvotes: 0
Views: 963
Reputation: 477010
Every constructor of every class constructs all the immediate non-virtual base classes. That explains recursively what happens in your setup.
By contrast, virtual base classes are constructed by the constructor of the most-derived class.
Here's a typical example which mentions the base constructors explicitly:
struct A { A(int, int) { /* ... */ ; };
struct B : A { B(char, bool) : A(2, 3) { /* ... */ };
struct C : B { C() : B('x', false) { /* ... */ };
C c; // calls A::A(2, 3), then B::B('x', false), then C::C()
Upvotes: 0
Reputation: 59
AFAIK, the constructor of A will be responsible for the initialisation of A's data members, as classes are constructed from the top down, or Base-before-Derived. This is why you can't use a pure virtual member function in a constructor, as the derived class in which it is defined has not been created yet.
Upvotes: 0
Reputation: 7905
It could be any of the classes A through Z, it completely depends on your situation. If class A takes param a b and c in its constructor then class B must provide these, if it in turn in its constructor expects a b c to be passed then it would be down to class C to provide these and so on. A child class may chose to provide a value which has not been passed in the constructor though and therefore subsequent children would no longer need to provide this value.
Upvotes: 0
Reputation: 57678
Any class derived along the chain can be responsible for initializing the data members depending on their accessibility.
One common method is to have class A`s constructor demand values for the data members. Class B would add these variables to it's constructor and so on.
Upvotes: 0
Reputation: 29981
When you inherit from a class, the base class's constructor is called prior to the derived class's. You can control what gets passed to it using the initializer list:
struct A
{
A();
A(int);
}
struct B
{
B(){} // A() is called implicitly.
B(int x) : A(x) {} // A(int) is called explicitly.
}
Upvotes: 1