我有一个名为Panel的基类,其中存储了一些关于窗口的信息,然后,我有所有控件的子类:Button,Label等。在基类中,我有virtual void ApplySchemeSettings(Scheme* scheme) { }
方法,在Panel(Panel* parent)
构造函数中调用。但是,不是子类,而是调用基类(ApplySchemeSettings
)中的Panel
。
class Panel
{
[...]
public:
virtual void ApplySchemeSettings(Scheme* scheme) { };
Panel(Panel* parent)
{
[...]
this->ApplySchemeSettings(scheme());
};
}
class Frame : public Panel
{
[...]
public:
void ApplySchemeSettings(Scheme* scheme)
{
this->border = scheme->GetBorder("FrameBorder");
}
}
我无法将ApplySchemeSettings
声明为抽象,因为子类是由用户创建的。
答案 0 :(得分:8)
在构造函数内部,虚函数的行为与您的预期不同。特别是,对构造函数内的虚函数的任何调用将始终解析对当前类中声明的函数版本的调用。这样做的原因是在对象构造期间,类通过首先构造最多的基类,然后是它的子类,然后是它的子类等来构造。因此,在对象构造期间,派生类直到基类才被初始化。类构造函数完成运行。如果你能够调用一个虚函数并让它解析为基类构造函数中最大的派生版本,那么你将在一个尚未初始化的类上调用一个方法 - 甚至不是默认的数据成员的构造函数尚未被调用。
您需要找到其他方法来解决此问题。例如,您可能有一个两步构造,在调用构造函数后调用一些init()
方法。但是,没有办法从构造函数安全地调用虚函数的派生版本。
希望这有帮助!