constructor calling order with composition

巧了我就是萌 提交于 2020-01-02 08:54:49

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!