小编典典

在构造函数中调用虚拟方法:Java和C ++之间的区别

java

在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();
    }
}

这将输出

Base::Base()
Derived::virt()
Derived::Derived()
Derived::virt()

但是,在C ++中,结果是不同的:

Base::Base()
Base::virt() // ← Not Derived::virt()
Derived::Derived()
Derived::virt()

(有关C ++代码,请参见http://www.parashift.com/c++-faq-lite/calling-virtuals-from-
ctors.html)

是什么导致Java和C ++之间的这种差异?是vtable初始化的时间吗?

编辑: 我确实了解Java和C ++机制。我想知道的是此设计决策背后的见解。


阅读 224

收藏
2020-09-24

共1个答案

小编典典

两种方法显然都有缺点:

  • 在Java中,调用转到无法this正确使用的方法,因为该方法的成员尚未初始化。
  • 在C 中,如果您不知道C 如何构造类,则将调用一种不直观的方法(即,不是派生类中的方法)。

为什么 每种语言都这样做是一个悬而未决的问题,但是两种语言都可能声称是“更安全”的选择:C
++的方法可以防止使用未初始化的成员;Java的方法允许(在某种程度上)类的构造函数中的多态语义(这是一个完全有效的用例)。

2020-09-24