Invoking virtual method in constructor: difference between Java and C++

c++, java, object-lifetime, virtual-functions, vptr

Solution

Both approaches clearly have disadvatages:

- In Java, the call goes to a method which cannot use `this` properly because its members haven’t been initialised yet.

- In C++, an unintuitive method (i.e. not the one in the derived class) is called if you don’t know how C++ constructs classes.

Why each language does what it does is an open question but both probably claim to be the “safer” option: C++’s way prevents the use of uninitialsed members; Java’s approach allows polymorphic semantics (to some extent) inside a class’ constructor (which is a perfectly valid use-case).

Problem

In Java: ``` class Base { public Base() { System.out.println("Base::Base()"); virt(); } void virt() { System.out.println("Base::virt()"); } } class Derived extends Base { public Derived() { System.out.println("Derived::Derived()"); virt(); } void virt() { System.out.println("Derived::virt()"); } } public class Main { public static void main(String[] args) { new Derived(); } } ``` This will output ``` Base::Base() Derived::virt() Derived::Derived() Derived::virt() ``` However, in C++ the result is different: ``` Base::Base() Base::virt() // ← Not Derived::virt() Derived::Derived() Derived::virt() ``` (See http://www.parashift.com/c++-faq-lite/calling-virtuals-from-ctors.html for C++ code) What causes such a difference between Java and C++? Is it the time when vtable is initialized? EDIT: I do understand Java and C++ mechanisms. What I want to know is the insights behind this design decision.

Original source