5

我有一个名为 Panel 的基类,其中存储了有关窗口的一些信息,然后,我有所有控件的子类:按钮、标签等。在基类中,我有在构造函数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为抽象,因为子类是由用户创建的。

4

1 回答 1

8

在构造函数内部,虚函数的行为并不像您预期​​的那样。特别是,在构造函数中对虚函数的任何调用都将始终解析对当前类中声明的函数版本的调用。原因是在对象构造过程中,首先构造一个基类,然后构造它的子类,然后构造它的子类,等等。因此,在对象构造过程中,派生类直到基类才被初始化。类构造函数完成运行。如果您能够调用虚函数并将其解析为基类构造函数内的最派生版本,那么您将调用一个尚未初始化的类的方法 - 甚至不是默认值数据成员的构造函数会被调用。

您将需要找到其他方法来解决此问题。例如,您可能有一个两步构造,其中init()在调用构造函数之后调用某个方法。但是,没有办法安全地从构造函数调用最派生版本的虚函数。

希望这可以帮助!

于 2012-06-19T19:07:10.017 回答