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.
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.
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.
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.
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.
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.
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.
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.
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.
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With