Search code examples
c++classinheritancevirtual

Virtual method not being called


I have a base class called Panel, where some information about a window is stored, then, I have subclasses for all the controls: Button, Label etc. In the base class, I have the virtual void ApplySchemeSettings(Scheme* scheme) { } method, which is called within the Panel(Panel* parent) constructor. But instead of the subclass, the ApplySchemeSettings from the base class (Panel) is being called.

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");
    }
}

I can't declare ApplySchemeSettings as abstract because the subclasses is made by user.


Solution

  • Inside of a constructor, virtual functions don't behave as you might expect. In particular, any call to a virtual function inside a constructor will always resolve the call to the version of the function declared inside the current class. The reason for this is that during object construction, a class is constructed by first having the most base class constructed, then its child class, then its child class, etc. Consequently, during object construction, the derived classes are not initialized until the base class constructors finish running. If you were to be able to call a virtual function and have it resolve to the most derived version inside of a base class constructor, you would be calling a method on a class that hadn't yet been initialized at all - not even the default constructors for the data members would have been called yet.

    You will need to find some other approach to solving this problem. You might, for example, have a two-step construction in which you call some init() method after calling the constructor. However, there is no way to safely call the most derived version of a virtual function from the constructor.

    Hope this helps!