【发布时间】:2021-06-19 15:43:06
【问题描述】:
我正在尝试从父级调用覆盖的函数,但发现它只是崩溃了。
这很难描述,所以这里是最小的可重现代码:
#include <iostream>
class A
{
public:
A()
{
init1();
}
void init1()
{
printf("1");
init2();
printf("2");
}
virtual void init2() = 0;
};
class B : public A
{
public:
B()
: A()
{}
void init2() override
{
printf("hello");
}
};
int main()
{
B b;
return 0;
}
在 MSVC 2019 上它崩溃了,在 http://cpp.sh/ 上它输出“1”,然后 main() 返回 0,但我们从未看到 "hello" 或 "2"。
-
为什么会崩溃?从低层次的角度会发生什么?
A是否试图调用自己的init2()? -
有没有办法做到这一点,所以我不必在每个派生类中,在其构造函数中添加
init2()?
【问题讨论】:
-
在
A的构造函数中调用init1();时出现问题。在构造函数和析构函数期间调用虚函数是危险的,因为最完全派生的类实际上并不处于有效状态——A的构造函数必须在B执行之前完全完成,但你必须有B表示init2();表示任何意思。 -
只有类
B的实例才能调用init2,因为只有类B具有init2的实现。因此从类A的构造函数调用init2是不行的。 -
我已阅读所有发送的链接。有趣的是,我无法用我自己的话找到任何东西。我发现很难描述并且得到了非常糟糕的结果。好吧,所以我想我的问题 1 已经回答了,请问您对 2) 有什么看法吗?
-
@Nox 有一个“工厂”,它通过构造
B类的实例,然后在它们上调用init2。不允许“外人”访问这些功能(将它们设为protected或private)。 -
要回答您的 2),您需要实现另一个
init函数并在构造对象后的某个时间调用它。