簡體   English   中英

Java和C ++之間的對象創建的主要區別是什么?

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

我正准備參加Java考試,之前考試的一個問題是:“Java和C ++之間的對象創建的主要區別是什么?”

我想我知道對象創建的基礎知識,例如如何調用構造函數以及Java中的初始化塊以及當一個類的構造函數調用另一個尚未構造的類的方法時會發生什么等等,但我可以找不到任何明顯的東西。 答案應該是一兩句話,所以我不認為Java中整個對象創建過程的描述就是他們想到的。

有任何想法嗎?

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

除了其他優秀的答案之外,還有一件非常重要的事情,通常被忽略/遺忘或誤解(這解釋了我為何詳細介紹了以下流程):

  • 在Java中,方法是虛擬的,即使從構造函數調用(這可能導致錯誤)
  • 在C ++中,從構造函數調用虛擬方法時不是虛擬的(這可能會導致誤解)

什么?

  • 讓我們設想一個基類,使用虛方法foo()。
  • 讓我們想象一個Derived類,繼承自Base,它重寫方法foo()

C ++和Java之間的區別是:

  • 在Java中,從Base類構造函數調用foo()將調用Derived.foo()
  • 在C ++中,從Base類構造函數調用foo()將調用Base.foo()

為什么?

每種語言的“錯誤”都不同:

  • 在Java中,調用構造函數中的任何方法都可能導致細微的錯誤,因為重寫的虛方法可能會嘗試訪問在Derived類中聲明/初始化的變量。

從概念上講,構造函數的工作是使對象存在(這不是一個普通的壯舉)。 在任何構造函數中,整個對象可能只是部分形成 - 您只能知道基類對象已經初始化,但您無法知道哪些類是從您繼承的。 但是,動態綁定的方法調用會在轉發層次結構中“前進”或“向外”。 它在派生類中調用方法。 如果你在構造函數中執行此操作,則調用可能操作尚未初始化的成員的方法 - 這是一個確定的災難方法。

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

  • 在C ++中,必須記住虛擬將無法按預期工作,因為只會調用當前構造類的方法。 原因是避免訪問數據成員甚至是尚不存在的方法。

在基類構造期間,虛函數永遠不會歸結為派生類。 相反,該對象的行為就像它是基本類型一樣。 非正式地說,在基類構建期間,虛函數不是。

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

除了堆/堆棧問題,我會說:C ++構造函數具有初始化列表,而Java使用賦值。 有關詳細信息,請參閱http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.6

我會回答:C ++允許在任何地方創建一個對象:堆,堆棧,成員。 Java強制您始終在堆上分配對象。

在Java中,執行Java代碼的Java虛擬機(JVM) 必須 被創建的所有對象可能1日志(或對它們的引用是精確的),以便為它們分配內存以后可以自動垃圾收集對象時被釋放不再引用了。

編輯:我不確定這是否可以歸因於嚴格意義上的對象創建,但它確實在創建和賦值給變量之間發生,即使沒有顯式賦值(當你創建一個沒有賦值的對象時,JVM有之后一段時間自動釋放它,因為沒有更多的引用)。

在C ++中,只有在堆棧上創建的對象才會自動釋放(當它們超出范圍時),除非您使用某種機制來為您處理此問題。

1 :取決於JVM的實現。

C ++和Java中的構造函數之間存在一個主要的設計差異。 其他差異來自此設計決策。

主要區別在於JVM在開始執行任何構造函數之前首先將所有成員初始化為零。 在C ++中,成員初始化是構造函數的一部分。

結果是在執行基類構造函數期間,在C ++中,派生類的成員尚未初始化! 在Java中,它們已被零初始化。

因此,在paercebal的答案中解釋了規則,即從構造函數調用的虛擬調用不能下降到派生類中。 否則可以訪問未初始化的成員。

假設c ++在進行新調用時使用alloc(),那么這可能就是他們正在尋找的東西。 (我不懂C ++,所以在這里我可能會非常錯誤)

Java的內存模型在需要時分配一塊內存,並且對於每個新內存使用這個預分配區域。 這意味着java中的一個新東西只是設置一個指向內存段的指針並移動空閑指針,而C ++中的新函數(授予它在后台使用malloc)將導致系統調用。

這使得用Java創建的對象比使用malloc的語言更便宜; 至少在沒有初始化的情況下。

簡而言之 - 在Java中創建對象很便宜 - 除非你創建它們,否則不要擔心它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM