Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 998
user1467310 Avatar asked Jun 19 '12 19:06

user1467310


People also ask

Can you call a virtual method?

Virtual functions allow a program to call methods that don't necessarily even exist at the moment the code is compiled. In C++, virtual methods are declared by prepending the virtual keyword to the function's declaration in the base class.

What if a virtual function is not overridden?

In addition, if you do not override a virtual member function in a derived class, a call to that function uses the function implementation defined in the base class. A function that has a deleted definition cannot override a function that does not have a deleted definition.

What is the true about virtual method?

A virtual method is one that is declared as virtual in the base class. A method is declared as virtual by specifying the keyword "virtual" in the method signature. A virtual method may or may not have a return type. Virtual methods allow subclasses of the type to override the method.

How do you call a virtual method from base class?

When you want to call a specific base class's version of a virtual function, just qualify it with the name of the class you are after, as I did in Example 8-16: p->Base::foo(); This will call the version of foo defined for Base , and not the one defined for whatever subclass of Base p points to.

How to call a virtual method from a non-virtual method?

In most cases, the virtual method is called indirectly by calling only an innocent non-virtual method from the constructor... Like in case of C++, a virtual method call directly or indirectly is most likely to be a bug in Java.

What happens when a virtual method is overridden by a class?

C#. If you call a virtual method from a Base class constructor and the virtual method is overridden by the Derived class, then the given virtual method of the Derived class is executed before the Derived constructor call but fortunately all Derived member variables (fields) are already initialized.

Is it possible to call a virtual method from a constructor?

Like in case of C++, a virtual method call directly or indirectly is most likely to be a bug in Java. As you will see in an example below there are a dozen ways to call a virtual method from your constructor "accidentally" while there are only a few valid reasons to call a virtual method from a Base class constructor.

What is difference between base class virtual and derived class virtual methods?

When the virtual methods are overriden in a derived class and that derived class uses an instance then invokes a derived class overriden method. When a virtual method is not overriden in a derived class and uses that derived class instance then invokes base class virtual method.


1 Answers

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!

like image 169
templatetypedef Avatar answered Sep 29 '22 16:09

templatetypedef