Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Virtual Functions during Construction. Why Java is different than C++

Tags:

java

c++

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.

like image 818
Efi MK Avatar asked Aug 26 '12 21:08

Efi MK


People also ask

Why there is no virtual function in Java?

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.

Why all functions in Java are virtual?

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.

Do virtual functions exist in Java?

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.

Does C have virtual functions?

Although C doesn't provide native support for virtual functions, you can emulate virtual functions in C if you attend to all the details.


2 Answers

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!].)

like image 199
Kerrek SB Avatar answered Sep 18 '22 01:09

Kerrek SB


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.

like image 31
user207421 Avatar answered Sep 21 '22 01:09

user207421