【问题标题】:Why is the Base class data initialized before Derived class data为什么基类数据在派生类数据之前初始化
【发布时间】:2020-06-17 21:52:11
【问题描述】:
考虑这段代码:
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++ 不这样做呢?
因为,据我所知,它并没有更快什么的。
【问题讨论】:
标签:
c++
inheritance
initialization
【解决方案1】:
1) 主要原因是 - Derived 类应该可以访问 Base 类字段。
让我用一个例子来解释:
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”,因为Derived() 中的m_i=1; 将首先发生,m_i{10} 将首先发生接下来发生,它看起来很混乱。
2)我也可以考虑另一个原因:
想象一下 - Base() 构造函数抛出异常,必须自己清理。
如果我们已经初始化了Derived,这意味着我们现在也必须在Derived 之后进行清理,这是开销。