2016-12-02 67 views
1

Pokemon是一類。考慮這個片段:「丟失」堆棧對象會發生什麼?

Pokemon Eve(4,3); //call to constructor, creating first object on the stack 
Eve=Pokemon(3,5); //call to constructor again, creating a second object on the stack 

兩個對象都在堆棧上創建。第二行執行後,第一個對象(帶有參數4,3)不能再被訪問。它會發生什麼?用什麼術語來描述這個過程?垃圾收集?

回答

6

我想你誤解了正在發生的事情。最初創建爲Eve的對象在第二行後不會「丟失」。事實上,它之後仍然是同一個對象(我的意思是它仍然具有相同的內存地址)。第二行通過調用對象Eve上的賦值運算符爲對象分配不同的值。傳遞給賦值運算符的參數是由Pokemon(3,5)創建的臨時對象。

它是上述臨時對象 - Pokemon(3,5)它在第二行後被銷燬。它的銷燬不是「垃圾收集」,甚至是堆釋放,因爲它首先是堆棧對象,因此不需要這樣做。

我想你正在考慮Java/C#或類似的託管語言,只有對象引用而不是直接對象。在上面的代碼C++中,你直接處理對象。要看到的東西等同於你心裏有什麼,看看這個:

Pokemon* Eve = new Pokemon(4,3); 
Eve=new Pokemon(3,5); 

這裏,我們使用指針和堆,而不是堆棧。在這種情況下,第二行確實會丟失原始對象,因爲它是重新分配的指針。這是排序類似於在Java/C#中發生的情況,只是正常分配。當然,區別在於C++沒有任何垃圾收集器,所以在上面,原始對象在內存泄漏的意義上真正失去了意義。

1

對象不是在堆上創建的,而是直接在堆棧上創建的,因此沒有空間丟失(即沒有分配的空間變得無法訪問) - 分配只是簡單地重用了由Eve初始化分配的內存。

編輯:關於「覆蓋」爭用更仔細的措詞。

+0

我不會說分配的空間是「簡單覆蓋」的。 C++賦值運算符在覆蓋任何內容之前可能會做很多事情。根據'operator =()'的實現,它可能不會覆蓋任何東西! –

+0

這正是默認實現所發生的情況,並且可以說,這就是任何理智的重寫應該做的事情,就分配語義而言。誠然,這個問題提供了一個很好的機會,可以爲C++中的特殊操作符插入深入的咆哮,但我非常懷疑OP要求這樣做。 – shinobi

+1

非常真實,這就是爲什麼我沒有downvote。這完全取決於OP的'口袋妖怪'類中發生了什麼。重寫'operator =()'的最明顯的原因是做指針的深層副本,它不僅僅是「簡單地覆蓋」類內容。我的評論更多的是指出,我們不一定會對OP的「口袋妖怪」課程做出假設,並做出一攬子聲明。 –

3

它被稱爲「賦值運算符」或「=」。

第二個對象是臨時對象,而不是第一個對象。構造完成後,將調用第一個對象的賦值運算符,以將第二個對象的值分配給第一個對象。

之後,第二個對象的析構函數被調用,第二個對象被銷燬。去哪裏?向天空中的巨大桶鬥。它消失了。

相關問題