为什么 Base class 数据在 Derived class 数据之前初始化

Why is the Base class data initialized before Derived class data

考虑这段代码:

class Base {
public:
  Base(): m_i{10} {}
private:
  int m_i;
};

class Derived: public Base {
public:
  Derived(): m_f{100.0} {}
private:
  float m_f;
};

int main() {
  Derived d;
}

Derived d; 实例化时,C++ 首先调用 Base() 构造函数并初始化 Base 的数据 - m_i - 然后才调用 Derived() 构造函数和初始化 Derived 的数据 - m_f.

但这是什么原因呢?

为什么 C++ 不反其道而行之?

因为据我所知,它并没有更快之类的。

1) 主要原因是 - Derived class 应该可以访问 Base class 字段。

让我用一个例子来解释:

class Base {
public:
  Base(): m_i(10) {}
protected:
  int m_i;
};

class Derived: public Base {
public:
  Derived(): m_f(100.0) {
    m_i = 1;
  }
  void print() {
    std::cout << "Derived m_f=" << m_f << ", m_i=" << m_i << '\n';
  }
private:
  float m_f;
};

int main() {
  Derived d;
  d.print(); // prints: "Derived m_f=100, m_i=1"
}

如果初始化以相反的方式发生 Derived 可以访问 Base 中未初始化的数据,这很糟糕。

此外 Derived() 构造函数无法正确更改 Base 字段值,您会打印出“Derived m_f=100, m_i=10”,因为 m_i=1;Derived() 会先发生,然后 m_i{10} 会发生,这看起来很混乱。

2)我也能想到另一个原因:

想象一下 - Base() 构造函数抛出异常并且必须自己清理。

如果我们已经初始化了 Derived 这意味着我们现在也必须在 Derived 之后进行清理,这是开销。