在初始化变量之前调用父类构造函数吗?

时间:2013-03-12 16:21:42

标签: c++ class inheritance

在初始化变量之前调用父类构造函数,还是编译器首先初始化类的变量?

例如:

class parent {
  int a;
public:
  parent() : a(123) {};
};

class child : public parent {
  int b;
public:
            // question: is parent constructor done before init b?
  child() : b(456), parent() {};
}

5 个答案:

答案 0 :(得分:16)

是的,基类在派生类的成员之前和构造函数体执行之前初始化。

12.6.2初始化基数和成员[class.base.init]

  

在非委托构造函数中,初始化继续进行   以下顺序:

     

- 首先,仅适用于最多的构造函数   派生类(1.8),虚拟基类按顺序初始化   它们出现在深度优先的从左到右的遍历中   基类的非循环图,其中“从左到右”是基数的顺序   派生类中基类的外观   基本符列表。

     

- 然后,在中初始化直接基类   声明顺序,因为它们出现在base-specifier-list中   (不管mem-initializers的顺序如何)。

     

- 然后,非静态   数据成员按照在其中声明的顺序进行初始化   类定义(再次无论顺序如何   MEM-初始化)。

     

- 最后,复合声明了   构造函数体被执行。

答案 1 :(得分:3)

是的,始终在派生类之前调用​​父构造函数。否则,派生类不能“改变”父类设置的内容。

答案 2 :(得分:2)

正如一些建议一样,如果您不确定,通常可以自己测试这样的事情:

#include <iostream>
using namespace std;

class parent {
protected:
  int a;
public:
  parent() : a(123) { cout << "in parent(): a == " << a << endl; };
};

class child : public parent {
  int b;
public:
            // question: is parent constructor done before init b?
  child() : b(456), parent() { cout << "in child(): a == " << a << ", b == " << b << endl; };
};

int main() {
  child c;
  return 0;
}

打印

in parent(): a == 123
in child(): a == 123, b == 456

答案 3 :(得分:0)

是的,对象的构造从父类开始并到达子类,因此构造函数调用按此顺序进行。在破坏的情况下,这恰恰相反。

答案 4 :(得分:0)

将派生类视为其基类的额外添加或扩展,添加因此它添加到某些东西(这个东西必须已经存在)。 那么,另一个问题是成员的初始化。在这里,您提供了默认构造函数

public:
  parent() : a(123) {};

因此,即使您以这种方式创建父级,该成员也将使用123进行默认初始化:

parent p;

如果没有默认构造函数初始化具有值

的对象
class parent {
public:
  int a;
};

比成员默认的那样,如果类是P.O.D那么int将默认初始化为0,但如果不是,即你提供更多成员,如字符串或向量

class parent {
public:
  int a;
  std::string s;
  std::vector<int> v;
};
如果没有初始化它的默认构造函数,

int将具有随机值。