14

I have some doubts about construction and initialization order guarantees in C++. For instance, the following code has four classes X, Y, Z and W. The main function instantiates an object of class X, which contains an object of class Y, and derives from class Z, so both constructors will be called. Additionally, the const char* parameter passed to X's constructor will be implicitly converted to an object of class W, so W's constructor must also be called.

What are the guarantees the C++ standard gives on the order of the calls to the copy constructors? Or, equivalently, what this program is allowed to print?

#include <iostream>

class Z {
   public:
   Z() { std::cout << "Z" << std::endl; }
};

class Y {
   public:
   Y() { std::cout << "Y" << std::endl; }
};

class W {
   public:
   W(const char*) { std::cout << "W" << std::endl; }
};

class X : public Z {
   public:
   X(const W&) { std::cout << "X" << std::endl; }
   private:
   Y y;
};

int main(int, char*[]) {
   X x("x");
   return 0;
}

edit: Is this correct?

   W      |
 /   \    |
Z     Y   |
 \   /    |
   X      V
4

5 回答 5

23

在所有类中保证构造顺序:基类,从左到右指定,后跟按类定义中声明的顺序的成员变量。类的构造函数体在其所有基类和成员的构造完成后执行。

在您的示例X中,它派生自Z并包含Y,因此Z首先构造基础对象,然后构造Y成员y,然后构造X完成,并执行X构造函数主体。

临时W需要传递给 的构造函数X,所以它是在构造x开始之前构造的,一旦初始化x完成就会被销毁。

所以程序必须打印:

W
Z
Y
X
于 2010-03-25T15:57:54.653 回答
8

1)首先,需要计算参数。

2)然后构造基类。

3) 然后在类的声明中按照出现的顺序构造成员。

4) 然后调用 X 的构造函数

于 2010-03-25T15:54:02.730 回答
2

为了扩展 Charles Bailey 的答案,当您的基类被虚拟继承时,规则会发生变化。我总是忘记顺序是什么,IBM 网站说首先初始化虚拟基地,但我从来没有遇到过它实际上不仅仅是琐事的情况。

于 2010-03-25T17:26:52.840 回答
2
  1. W 对象将在调用 X 的构造函数之前构造。
  2. Z,作为 X 的基类,会在 X 的成员之前初始化。
  3. Y 将在成员初始化期间初始化
  4. X 的构造函数将运行。
于 2010-03-25T15:54:54.877 回答
2

总结一下这些规则:

  1. 参数,从右到左
    a。最正确
    b. 右二
  2. 基类
  3. 虚拟基地
  4. 从左到右的基类
  5. 成员在课堂上的声明顺序
  6. 被调用类的构造函数
于 2015-08-26T08:05:58.340 回答