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

发布于 2024-09-25 16:45:02 字数 216 浏览 9 评论 0原文

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

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

有什么想法吗?

I'm preparing for an exam in Java and one of the questions which was on a previous exam was:"What is the main difference in object creation between Java and C++?"

I think I know the basics of object creation like for example how constructors are called and what initialization blocks do in Java and what happens when constructor of one class calls a method of another class which isn't constructed yet and so on, but I can't find anything obvious. The answer is supposed to be one or two sentences, so I don't think that description of whole object creation process in Java is what they had in mind.

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

呆橘 2024-10-02 16:45:02

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

What is the main difference in object creation between Java and C++?

Unlike Java, in C++ objects can also be created on the stack.

For example in C++ you can write

Class obj; //object created on the stack

In Java you can write

Class obj; //obj is just a reference(not an object)
obj = new Class();// obj refers to the object
夏末 2024-10-02 16:45:02

除了其他出色的答案之外,还有一件事非常重要,并且通常被忽略/忘记或误解(这解释了为什么我详细介绍了下面的过程):

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

什么?

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

C++ 和 Java 之间的区别是:

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

为什么?

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

  • 在 Java 中,调用构造函数中的任何方法都可能导致微妙的错误,因为重写的虚拟方法可能会尝试访问在派生类中声明/初始化的变量。

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

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

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

在基类构造期间,虚函数永远不会进入派生类。相反,该对象的行为就像它是基本类型一样。通俗地说,在基类构造过程中,虚函数不是。

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


In addition to other excellent answers, one thing very important, and usually ignored/forgotten, or misunderstood (which explains why I detail the process below):

  • In Java, methods are virtual, even when called from the constructor (which could lead to bugs)
  • In C++, virtual methods are not virtual when called from the constructor (which could lead to misunderstanding)

What?

  • Let's imagine a Base class, with a virtual method foo().
  • Let's imagine a Derived class, inheriting from Base, who overrides the method foo()

The difference between C++ and Java is:

  • In Java, calling foo() from the Base class constructor will call Derived.foo()
  • In C++, calling foo() from the Base class constructor will call Base.foo()

Why?

The "bugs" for each languages are different:

  • In Java, calling any method in the constructor could lead to subtle bugs, as the overridden virtual method could try to access a variable which was declared/initialized in the Derived class.

Conceptually, the constructor’s job is to bring the object into existence (which is hardly an ordinary feat). Inside any constructor, the entire object might be only partially formed – you can know only that the base-class objects have been initialized, but you cannot know which classes are inherited from you. A dynamically-bound method call, however, reaches “forward” or “outward” into the inheritance hierarchy. It calls a method in a derived class. If you do this inside a constructor, you call a method that might manipulate members that haven’t been initialized yet – a sure recipe for disaster.

Bruce Eckel, http://www.codeguru.com/java/tij/tij0082.shtml

  • In C++, one must remember a virtual won't work as expected, as only the method of the current constructed class will be called. The reason is to avoid accessing data members or even methods that do not exist yet.

During base class construction, virtual functions never go down into derived classes. Instead, the object behaves as if it were of the base type. Informally speaking, during base class construction, virtual functions aren't.

Scott Meyers, http://www.artima.com/cppsource/nevercall.html

孤蝉 2024-10-02 16:45:02

除了堆/堆栈问题之外,我想说的是:C++ 构造函数具有初始化列表,而 Java 使用赋值。请参阅http://www.parashift.com/c++-faq- lite/ctors.html#faq-10.6 了解详细信息。

Besides heap/stack issues I'd say: C++ constructors have initialization lists while Java uses assignment. See http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.6 for details.

铃予 2024-10-02 16:45:02

我的回答是:C++ 允许在任何地方创建对象:在堆、堆栈、成员上。 Java 强制您在堆上分配对象,总是

I would answer: C++ allows creating an object everywhere: on the heap, stack, member. Java forces you allocate objects on the heap, always.

一绘本一梦想 2024-10-02 16:45:02

在 Java 中,执行 Java 代码必须的 Java 虚拟机 (JVM) 可能1记录正在创建的所有对象(或者准确地说是对它们的引用),以便内存当不再引用对象时,为它们分配的空间可以通过垃圾收集自动释放。

编辑:我不确定这是否可以归因于严格意义上的对象创建,但它肯定会在创建和分配变量之间的某个时间发生,即使没有显式分配(当您创建对象时)如果不分配它,JVM 必须在一段时间后自动释放它,因为没有更多的引用)。

在 C++ 中,只有在堆栈上创建的对象才会自动释放(当它们超出范围时),除非您使用某种机制来处理此问题。

1:取决于 JVM 的实现。

In Java, the Java Virtual Machine (JVM) that executes Java code has to might1 log all objects being created (or references to them to be exact) so that the memory allocated for them can later be freed automatically by garbage collection when objects are not referenced any more.

EDIT: I'm not sure whether this can be attributed to object creation in the strict sense but it surely happens somewhen between creation and assignment to a variable, even without an explicit assignment (when you create an object without assigning it, the JVM has to auto-release it some time after that as there are no more references).

In C++, only objects created on the stack are released automatically (when they get out of scope) unless you use some mechanism that handles this for you.

1: Depending on the JVM's implementation.

终遇你 2024-10-02 16:45:02

C++ 和 Java 中的构造函数之间存在一个主要的设计差异。此设计决策还存在其他差异。

主要区别在于,JVM 在开始执行任何构造函数之前首先将所有成员初始化为零。在 C++ 中,成员初始化是构造函数的一部分。

结果是,在 C++ 中,在执行基类构造函数期间,派生类的成员尚未初始化!在 Java 中,它们已被零初始化。

因此,paercebal 的回答中解释的规则是,从构造函数调用的虚拟调用不能下降到派生类。否则可以访问未初始化的成员。

There is one main design difference between constructors in C++ and Java. Other differences follow from this design decision.

The main difference is that the JVM first initializes all members to zero, before starting to execute any constructor. In C++, member initialization is part of the constructor.

The result is that during execution of a base class constructor, in C++ the members of the derived class haven't been initialized yet! In Java, they have been zero-initialized.

Hence the rule, which is explained in paercebal's answer, that virtual calls called from a constructor cannot descend into a derived class. Otherwise uninitialized members could be accessed.

兮颜 2024-10-02 16:45:02

假设 c++ 在进行新调用时使用 alloc(),那么这可能就是它们的含义
寻找。 (我不懂 C++,所以在这里我可能会错得很)

Java 的内存模型会在需要时分配一块内存,并且对于每个新的它使用
这个预先分配的区域。这意味着java中的new只是设置一个指向a的指针
内存段并在 C++ 中的 new 时移动空闲指针(假设它在后台使用 malloc)
将导致系统调用。

这使得在 Java 中创建对象比使用 malloc 的语言更便宜;
至少在没有发生初始化时是这样。

简而言之 - 在 Java 中创建对象很便宜 - 除非您创建大量对象,否则不必担心。

Assuming that c++ uses alloc() when the new call is made, then that might be what they are
looking for. (I do not know C++, so here I can be very wrong)

Java's memory model allocates a chunk of memory when it needs it, and for each new it uses of
this pre-allocated area. This means that a new in java is just setting a pointer to a
memory segment and moving the free pointer while a new in C++ (granted it uses malloc in the background)
will result in a system call.

This makes objects cheaper to create in Java than languages using malloc;
at least when there is no initialization ocuring.

In short - creating objects in Java is cheap - don't worry about it unless you create loads of them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文