2013-03-15 93 views
-2

我對使用java或C++的對象的管理有疑問。對象的管理

的情況是,在C++中,當你想創建一個動態的對象,一個是生存比上創建它的塊範圍更多,你必須做一個新的,您將收到一個指針。否則,如果你只是想在塊範圍內使用這個對象,你不需要使用新的創建它...

但是在Java中,你總是必須使用new創建它們,因爲如果不是,對象爲null,您可以使用它。

這是爲什麼?它是如何工作的?

謝謝

+1

爲什麼?因爲Java和C++是具有完全不同對象模型和不同規則的兩種不同語言。 (他們都碰巧有一個關鍵字'新',具有不同的含義。) – aschepler 2013-03-15 14:44:38

回答

2

我能想到的最好的比喻,是在C各類++的行爲有些象Java原語。如果您在Java中聲明瞭一個原語,則不必使用new,您可以立即使用該變量。但是像C++中的大多數對象一樣,這樣的基元只能在當前範圍內生存。在C++中,如果你想讓一個對象存在於當前作用域之外,你需要告訴編譯器,因爲它必須在堆上分配內存而不是堆棧。您可以使用new來完成此操作。在Java中,所有對象(保存原語)都分配在堆上,堆棧中唯一的數據是對堆內存和原語的引用。因此,在Java中,所有內存分配均使用new完成。

以上是對Java中實際內存管理的簡化。有關基元的堆棧/堆內存更深入的討論,請看看here

+1

這裏有一個很好的堆棧/堆棧/基元與對象的解釋;以上是一些簡化。 http://stackoverflow.com/questions/3646632/does-the-java-primitives-go-on-the-stack-or-the-heap – James 2013-03-15 14:57:30

+0

那麼,這就是我暗示的「*有點*」。 ;)但是感謝鏈接,我將它包含在答案中。 – JSQuareD 2013-03-15 15:01:19

+0

嘿,只是幫助... – James 2013-03-15 15:08:55

0

基本上,這就是它的工作原理。一旦使用了新的關鍵字,那麼對象就會被創建並彈出到堆上。如果你沒有在方法外引用這個對象,那麼垃圾回收器會自動回收它。 我建議你閱讀一下Java堆和垃圾回收的基礎知識,以獲得更好的理解。那裏有很多資源。我總是爲新來的人推薦頭等書。

+0

問題是關於C++,在C++中沒有垃圾收集器... – JSQuareD 2013-03-15 14:51:03

+0

我看到OP瞭解它如何在C++中工作,但不是什麼「新」的點在Java中。 – James 2013-03-15 14:53:46

+0

啊,我只是反過來......重讀他的文章,我不再肯定這種方式或其他... – JSQuareD 2013-03-15 14:56:12

1

這種差異是因爲Java正在使用垃圾回收器進行內存管理。由於垃圾收集器在其作用域結束時(並且它沒有可達引用)會自動釋放對象,因此不需要有兩種不同的方法來創建對象。

你可以說,在Java對象自動的行爲類似於C++這是不初始化的對象,因爲你不必去想刪除它們。

0

在C++中,任何東西都可以在棧上分配(也就是當你說

ObjectType o; 
用C

++會發生什麼。

在Java中,只有原語確實在棧中分配。對象是從來沒有在棧上(這只是它是如何)。當你說

ObjectType o; 

在Java中,沒有對象被分配,只有一個「變量」。變量可以有一個對象的引用,但在日現在它沒有。從本質上講,它是等於說

ObjectType *o = NULL 
用C++

爲了實際分配一個對象本參考引用,你必須在Java中使用new

0

在C++中,當你想要創建一個動態對象時,你必須創建一個新的對象,它必須在創建它的地方創建一個新的塊,然後你會收到一個指針。

操作者在C++分配在堆空間。堆是主存的大部分。如果你這樣做,你有責任在使用免費操作員完成該空間時釋放該空間。

否則,如果你只是想在塊範圍內使用這個對象,你不需要它使用新的創造......

當你在C++中聲明變量,內存分配在堆棧。堆棧是,當地的數據存儲和一切你上推(添加)在執行功能會自動彈出(刪除)函數返回時。堆棧通常比堆小很多,但使用它有很多優點:您不需要擔心內存管理,速度更快等。

但是在Java中,您總是必須使用new創建它們,因爲如果不是,則該對象爲null,您可以使用它。

當你在聲明Java變量,它們再次存儲在堆棧上 你知道,你不上的原始數據類型調用(例如int i = new int(3);)。當你這樣做你Object x;聲明x將是一個參考Object類型的對象。但是,你不要一個值分配給它,這樣的引用是(不是對象,因爲沒有一個)。粗略地說,在Java中,運算符在堆上分配空間,調用它所調用的對象的構造函數,並返回對構造對象的引用。與C++的區別在於你不需要自己釋放對象 - 有一個垃圾回收器。本質上,它所做的是監視有多少引用指向一個對象,如果它們歸零,則會自動刪除該對象。

所以,當你做

Object y = new Object(); 
x = y;
你會得到兩個引用(x和y)指向同一個對象。當你在 bar()...部分函數調用這樣
Object foo() { 
    Object y = new Object(); 
    return y; 
}

void bar() { Object x = foo(); ... }

你將有參考 x,指着 foo()創建的對象。由於 foo已返回,因此 y引用已被釋放,因此在該程序的 ...部分中只能引用該對象。如果您不復制參考 barbar返回的任何位置,則會有0個對該對象的引用,並且垃圾收集器將 收集它(儘管不是立即)。

-Stan