当前位置: 首页 > 面试题库 >

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

东门航
2023-03-14
问题内容

在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 ++机制。我想知道的是此设计决策背后的见解。


问题答案:

两种方法显然都有缺点:

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

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



 类似资料:
  • 本文向大家介绍c++ 构造函数中调用虚函数的实现方法,包括了c++ 构造函数中调用虚函数的实现方法的使用技巧和注意事项,需要的朋友参考一下 我们知道:C++中的多态使得可以根据对象的真实类型(动态类型)调用不同的虚函数。这种调用都是对象已经构建完成的情况。那如果在构造函数中调用虚函数,会怎么样呢? 有这么一段代码: 输出: 0 1 2 也就是说,在构造函数中调用虚函数,调用的是正在构造的类中的虚函

  • 问题内容: 其实我不明白,无参数构造函数和默认构造函数有什么区别。 创建名为cFrame的Test对象时,这是否调用此类的默认构造函数? 问题答案: 该构造函数是一个无参数的构造函数,代表您的Java编译器插入; 它包含对(not )的调用,这是默认行为。如果实现任何构造函数,则不再收到默认的构造函数。 JLS-8.8.9。默认构造函数说(部分), 如果一个类不包含构造函数声明,则隐式声明一个没有

  • 问题内容: 对不起任何较小的语法错误或其他错误,我正在使用Jitsi模块进行此操作,并且对Java不太熟悉,因此想确认正在发生的事情以及为什么以及如何对其进行修复。 使用按名称加载类方法创建类B的实例时,应用程序正在执行此操作: 在类B中调用重写的load() 初始化变量(根据调试器调用“私有字符串testString = null”),将其无效。 这是预期的Java行为吗?是什么原因造成的?它是

  • 问题内容: 这可能只是个人喜好和工作流程的问题,但如果不止于此,我还是应该问一下。 在Java中,通过构造函数和通过静态方法(返回实例)创建实例之间有什么区别?例如,从我正在处理的项目中获取以下代码(在发布时手工编写,因此采用了一些快捷方式和自由): 在这种情况下,使用之间会有什么区别 和 除了在插件类中运行,因为它没有在构造函数中调用,所以只能在后者中运行? 在这种情况下,要澄清的是主要类别。

  • 问题内容: 我一直在做大学项目的作业。有一次,当您实际上可以使用构造函数方法来实现相同的结果时,我对于getter和setter的实际使用感到困惑。我已经搜索并找到许多答案,但没有令人满意的解释。我有如下laptop.java 和laoptopRecords.java调用构造函数为 在这里,我没有使用getter和setter方法,并且为每个便携式计算机对象都获得了理想的结果。 如果我以如下方式在

  • 我在react native中开发了几个类,出现了以下问题: 酒吧类: