此文为C++之父撰写,本篇为翻译
是的,但要小心。 它可能不会做你期望的。 在构造函数中, 虚拟调用机制被禁用,因为从派生覆盖 课程还没有发生。 对象是从基础向上构建的, “派生前的基础”。
考虑到
#include<string> #include<iostream> using namespace std; class B { public: B(const string& ss) { cout << "B constructor\n"; f(ss); } virtual void f(const string&) { cout << "B::f\n";} }; class D : public B { public: D(const string & ss) :B(ss) { cout << "D constructor\n";} void f(const string& ss) { cout << "D::f\n"; s = ss; } private: string s; }; int main() { D d("Hello"); }
程序编译并生成
B constructor
B::f
D constructor
注意 不是 D::f。 考虑如果规则不同会发生什么 D::f() 是 从 B::B() 调用:因为构造函数 D:: D() 尚未运行, D::f() 会尝试将其参数分配给未初始化的字符串 s。 结果很可能是立即崩溃。
破坏是“在基类之前的派生类”完成的,因此虚函数 与构造函数中的行为相同:仅使用局部定义 - 不使用 调用重写函数以避免触及(现已销毁) 对象的派生类部分。
有关详细信息,请参阅 D&E 13.2.4.2 或 TC++PL3 15.4.3。
有人建议此规则是一个实现工件。 这是 不是这样。 事实上,实施不安全规则会容易得多 从构造函数中调用虚函数与从其他函数中调用虚函数完全一样。 但是,这意味着不能编写任何虚函数来依赖 关于由基类建立的不变量。 那将是一团糟。
注意:可以结合这篇文章来看https://www.cnblogs.com/wozhuyinghao/p/17148698.html