为什么 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
之后进行清理,这是开销。
考虑这段代码:
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
之后进行清理,这是开销。