I had a test today and one of the questions was about using a virtual method in C++ constructor. I failed this question, I answered that there shouldn't be any problem, however after reading this I found out I was wrong.
So I understand that the reason for not allowing that is because the derived object is not fully initialized and therefore calling it's virtual method can cause invalid consequences.
My question how was it solved in Java/C# ? I know that I can call derived method in my base constructor, I would assume that these languages have exactly the same problem.
In Java Every non-static, non-final, and public method is a virtual function. These methods can be used to achieve polymorphism. The methods that can not be used to achieve the polymorphism never be virtual function. A static, final, and private method never be the virtual function.
In Java, all non-static methods are by default "virtual functions." Only methods marked with the keyword final, which cannot be overridden, along with private methods, which are not inherited, are non-virtual.
Every non-static method in Java is a virtual function except for final and private methods. The methods that cannot be used for the polymorphism is not considered as a virtual function. A static function is not considered a virtual function because a static method is bound to the class itself.
Although C doesn't provide native support for virtual functions, you can emulate virtual functions in C if you attend to all the details.
Java has a very different object model from C++. In Java, you cannot have variables which are objects of class type -- instead, you can only ever have references to objects (of class type). Therefore, all members of a class (which are only references) start out trivially as null
until the entire derived object has been set up in memory. Only then do the constructors run. Thus by the time a base constructor calls a virtual function, even if that function is overridden, the overridden function can at least correctly refer to members of the derived class. (Those members may not themselves be assigned yet, but at least they exist.)
(If it helps, you can also consider that every class without final
members in Java is technically default-constructible, at least in principle: Unlike in C++, Java has no such things as constants or references (which must be initialized in C++), and in fact there are no initializer lists at all. Variables in Java simply don't need to be initialized. They're either primitives which start as 0, or class type references which start as null
. One exception comes from non-static final
class members, which cannot be rebound and must actually be "initialized" by having precisely one assignment statement somewhere in every constructor [thanks to @josefx for pointing this out!].)
understand that the reason for not allowing that is because the derived object is not fully initialized and therefore calling it's virtual method can cause invalid consequences
Wrong. C++ will call the base class's implementation of the method, not the derived class's. There are no 'invalid consequences'. The only valid reason for avoiding the construct is that the behavior sometimes comes as a surprise.
This is different from Java because Java calls the derived class's implementation.
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