问题
I have a class A and Class B . Class C derives from Class B and has Class A object as composition . http://ideone.com/JGT48M
#include "iostream"
using namespace std;
class A {
int i;
public:
A(int ii) : i(ii) {
cout << "\n Constructor of A is called \n";
}
~A() {
cout << "\n destructor of A is called \n";
}
void f() const {}
};
class B {
int i;
public:
B(int ii) : i(ii) {
cout << "\n Constructor of B is called \n";
}
~B() {
cout << "\n destructor of B is called \n";
}
void f() const {}
};
class C : public B {
A a;
public:
C(int ii) : a(ii), B(ii) {
cout << "\n Constructor of C is called \n";
}
~C() {
cout << "\n destructor of C is called \n";
} // Calls ~A() and ~B()
void f() const { // Redefinition
a.f();
B::f();
}
};
int main() {
C c(47);
} ///:~
I have read that constructors are called based on how they are called in my derived class constructor . What i mean is that let there be a class called REF derived from REF_BASE1 and REF_BASE2 then
REF (int ii) : REF_BASE2(ii), REF_BASE1 (ii) {
would mean that REF_BASE2 would be called first then REF_BASE1 and then REF constructor is called . and if we defined it like
REF (int ii) : REF_BASE1(ii), REF_BASE2 (ii) {
would mean that REF_BASE1 would be called first then REF_BASE2 and then REF constructor is called .
However in my program above i have explicitly "wrongly" stated that by internal composition variable A a be initialized first and then B should get initialized , yet the compiler does it the right way but fails to let me know of my mistake
output of above program irrespective of order i specify in derived class constcutor initialization list is
Constructor of B is called
Constructor of A is called
Constructor of C is called
destructor of C is called
destructor of A is called
destructor of B is called
My question is 1) why does compiler not complain ? or am i correct ? 2) is the order in derived constructor not followed strictly ?
回答1:
I will start with the second question:
2) is the order in derived constructor not followed strictly ?
The order is not the one that appears in your constructor's initialization list, but rather the one in which the base classes appear in your class definition.
So if your class definition looks like this:
struct A : B, C
{
// ...
};
Then the constructor of B
will be called before the constructor of C
, no matter what order you specify in the initialization list of A
's constructor.
Paragraph 12.6.2/10 of the C++11 Standard specifies:
In a non-delegating constructor, initialization proceeds in the following order:
— First, and only for the constructor of the most derived class (1.8), virtual base classes are initialized in the order they appear on a depth-first left-to-right traversal of the directed acyclic graph of base classes, where “left-to-right” is the order of appearance of the base classes in the derived class base-specifier-list.
— Then, direct base classes are initialized in declaration order as they appear in the base-specifier-list (regardless of the order of the mem-initializers).
— Then, non-static data members are initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializers).
— Finally, the compound-statement of the constructor body is executed.
Now the first question:
1) why does compiler not complain ?
The compiler may warn you that the initialization order in the constructor initializer list is different from the one in the base class list (GCC does with -Wall
), but does not have to. Eventually, only the latter matters.
来源:https://stackoverflow.com/questions/16873215/constructor-calling-order-with-composition