Java和C++在对象创建方面的主要区别是什么?

2022-09-02 02:24:12

我正在准备Java考试,上一次考试中的一个问题是:“Java和C++在对象创建方面的主要区别是什么?

我想我知道对象创建的基础知识,例如如何调用构造函数,初始化块在Java中的作用,以及当一个类的构造函数调用另一个尚未构造的类的方法时会发生什么,等等,但我找不到任何明显的东西。答案应该是一两句话,所以我不认为Java中对整个对象创建过程的描述是他们所想到的。

有什么想法吗?


答案 1

Java和C++在对象创建方面的主要区别是什么?

与Java不同,C++对象也可以在堆栈上创建。

例如,在C++中,您可以编写

Class obj; //object created on the stack

在Java中,你可以写

Class obj; //obj is just a reference(not an object)
obj = new Class();// obj refers to the object

答案 2

除了其他优秀的答案之外,有一件事非常重要,通常被忽视/遗忘,或误解(这解释了为什么我在下面详细介绍这个过程):

  • 在Java中,方法是虚拟的,即使从构造函数调用也是如此(这可能会导致错误)
  • 在C++中,从构造函数调用虚拟方法时不是虚拟的(这可能会导致误解)

什么?

  • 让我们想象一个基类,带有一个虚拟方法 foo()。
  • 让我们想象一个从 Base 继承的派生类,它重写了方法 foo()

C++和Java的区别在于:

  • 在Java中,从基类构造函数调用foo()将调用 Derived.foo()
  • 在C++中,从基类构造函数调用 foo() 将调用 Base.foo()

为什么?

每种语言的“错误”是不同的:

  • 在Java中,调用构造函数中的任何方法都可能导致细微的错误,因为被覆盖的虚拟方法可以尝试访问在 Derived 类中声明/初始化的变量。

从概念上讲,构造函数的工作是使对象存在(这几乎不是一个普通的壮举)。在任何构造函数中,整个对象可能只是部分形成的 – 您只能知道基类对象已被初始化,但您无法知道哪些类是从您那里继承的。但是,动态绑定的方法调用会“转发”或“向外”进入继承层次结构。它调用派生类中的方法。如果在构造函数中执行此操作,则调用一个可能操作尚未初始化的成员的方法 - 这肯定会造成灾难。

布鲁斯·埃克尔,http://www.codeguru.com/java/tij/tij0082.shtml

  • 在C++中,必须记住虚拟不会按预期工作,因为只会调用当前构造类的方法。原因是为了避免访问数据成员甚至尚不存在的方法。

在基类构造期间,虚函数永远不会下降到派生类中。相反,对象的行为就像它是基类型一样。非正式地说,在基类构造期间,虚函数不是。

斯科特·迈耶斯,http://www.artima.com/cppsource/nevercall.html