Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resolve C++ virtual functions from base class

Sorry if this is a dupe, I cant find an answer quite right.

I want to call a function from a base class member, and have it resolve to the subclass version. I thought declaring it virtual would do it, but it isn't. Here's my approach:

class GUIWindow
{
public:
    GUIWindow()
    {
        SetupCallbacks();
    }

    virtual void SetupCallbacks()
    {
         // This function always called
    }
};

class GUIListbox : public GUIWindow
{
public:
    void SetupCallbacks()
    {
        // This never called
    }
};

GUIListbox lb; // GUIWindow::SetupCallbacks is called :(

What am I doing wrong?

Many thanks

Si

like image 212
sipickles Avatar asked Dec 23 '22 05:12

sipickles


2 Answers

Never call a virtual function in the constructor.

like image 149
Khaled Alshaya Avatar answered Feb 21 '23 14:02

Khaled Alshaya


When you call virtual functions during construction of some class C (i.e. while the constructor of C is active), the virtual mechanism works, but it works in restricted mode. The resolution of the virtual calls in the class hierarchy is limited by the class that is currently being constructed (C). This means that the virtual calls will resolve as if the class C is the "final" class in the hierarchy, as if it has no descendants.

The same is true for destructors.

In your example, you are calling a virtual function from constructor of class GUIWindow. As long as the constructor of GUIWindow is active, its virtual mechanism will work as if there are no other classes derived from GUIWindow. This mechanism will completely ignore the existence of GUIListbox class. This is why the resolution of virtual call "stops" at GUIWindow and calls GUIWindow::SetupCallbacks, as if GUIListbox::SetupCallbacks doesn't exist.

You can read about in in C++ FAQ http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.5

like image 36
AnT Avatar answered Feb 21 '23 14:02

AnT