javac++virtual-functionsobject-lifetimevptr

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


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.


Solution

  • Both approaches clearly have disadvatages:

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