//This program is taken from http://www.learncpp.com/cpp-tutorial/114-constructors-and-initialization-of-derived-classes/
#include <iostream>
using namespace std;
class A
{
public:
A(int nValue)
{
cout << "A: " << nValue << endl;
}
};
class B: public A
{
public:
B(int nValue, double dValue)
: A(nValue)
{
cout << "B: " << dValue << endl;
}
};
int main()
{
B bClass(5, 4.3);
return 0;
}
When I run this:
$g++ inherit.cpp -o inherit
$ ./inherit
A: 5
B: 4.3
which is expected.
But when I change class B to this:
class B: public A
{
int something;
public:
B(int nValue, double dValue)
: something(nValue), A(nValue)
{
cout << "B: " << dValue << endl;
cout << "B.something: " << something << endl;
}
};
the output is:
$ ./inherit
A: 5
B: 4.3
B.something: 5
My question:
When the compiler goes through B’s initialization list, does it only search for the Base Class constructor and jump to it and not execute the other statements(something(nValue))
or does it execute all the statements till it finds the BaseClass constructor and simply does not execute the constructor body till Base Class constructor is done executing?
In other words would the value of B.something be set to nValue when the something(nValue) statement is first encountered or would it remain uninitialized till A(nValue) is called?
All sub-objects and non-static member objects of a class instance are initialized in fixed order, namely in the order of their declaration (which is: first all the subobjects in order (e.g.
A,B,Cforclass Foo : A, B, C), then the non-static member objects).The order in which you list initializers in the initializer list does not affect this behaviour; however, you should always write the IL in the correct order to avoid surprises and to make your code as easy to read as possible.
You should generally avoid having one object initializer depend on another object, but sometimes it may be necessary. If possible, just reuse the constructor argument, though. Example:
Now imagine we had instead
struct Foo : Bar, and you might be tempted to write an initializer forFooasa(a_), b(a), Bar(a, b). That would be a disaster. Writing the IL in order makes this impossible:Bar(a_, b_), a(a_), b(a_).