2017-07-02 104 views
2

這是一個基本的例子在堆或堆棧中創建構造函數的區別是什麼?

myclass * abc = new myclass() 

myclass abc 

的區別是什麼?在這兩種情況下,堆棧中創建的對象是abc?如果對象是在堆中創建的,有什麼不同?

從答案,我採取這一(請編輯如果不正確):如果我們要當它是出於沒有刪除類的變量

  1. 構造函數初始化類(成員)

  2. 範圍,我們應該把對象創造堆起來。

+5

你的意思是除了對象存儲在不同的地方?而且你需要一個指向堆分配對象的指針?也許你可以詳細闡述什麼是困擾你或者你在想什麼? –

+0

而且你需要(手動)管理使用'new'分配的對象的銷燬(而另一個會在其生命週期結束時自動銷燬) – UnholySheep

+0

我的意思是在這兩個代碼中,對象abc是在堆棧右側創建的?如何在堆中創建構造函數可以影響代碼? –

回答

5

儘管在例abc是在自動存儲器(通常稱爲「堆」)是不相同的種類的對象:

  • 在第一個例子abc是一個指針,它被存儲在堆棧中。但是,存在存儲在動態存儲器(通常稱爲「堆」)中的myclass類型的第二個對象。對象指針abc指向堆中的對象。
  • 在第二個示例中abc的類型爲myclass。這是創建的唯一對象。這兩種方法之間

主要區別在於,在動態存儲器中創建一個對象可以「活得比」在其內部的被創建它的功能。當指針abc超出範圍時,其堆對象保持活動狀態。例如,您可以在不進行復制的情況下從函數中返回它。

+0

@StelTeam你將通過一個指針訪問你的對象,這是一種不同的語法。您需要通過調用delete來手動刪除對象。 – dasblinkenlight

+0

謝謝你的幫助我如此多 –

+0

和1件事情如果指針超出範圍,那麼我如何訪問該對象? –

1

myclass * abc = new myclass();中,您創建了一個指向棧上myclass的指針和堆上myclass的實例。在myclass abc;中,您將在堆棧上創建myclass的實例。

有很多不同之處,但最直接的一點是當堆留在當前離開當前上下文(例如從函數返回)時釋放堆棧。因此,在第一個示例中,myclass的實例將保留在內存中,直到您手動釋放它爲止;而在第二個選項中,當您退出其寫入的函數或代碼塊時,它將自動清除。

1

從構造函數調用的角度來看,兩者基本沒有區別。在這兩種情況下,都會調用類的默認構造函數來構建對象。只是在myclass * abc = new myclass()的情況下,new運算符返回一個指向新創建對象的指針。

但是,主要區別在於堆棧內存和堆(動態)內存的概念。表達式myclass * abc = new myclass()爲堆中新創建的對象分配內存,而myclass abc從堆中分配內存。這種差異的一個含義是,您對堆中請求的內存負責,並且您必須自己釋放它,而對於在堆棧中分配的變量,編譯器會爲您執行內存刪除工作。考慮下面的簡單函數:

void fo() 
{ 
    myclass * abc1 = new myclass(); 
    myclass abc2; 

    // Use the declared variables. 

    // At the end, is everything OK? 
} 

在此功能的情況下,當函數返回,abc2的存儲器自動由編譯器釋放。編譯器還會刪除abc1指針,但不會執行關於此指針指向的內存的任何操作。這個微妙的特點導致notorious memory在這個函數泄漏。的fo地址這個錯誤以下修改後的版本:

void fo() 
{ 
    myclass * abc1 = new myclass(); 
    myclass abc2; 

    // At the end, manually free the memory that abc1 points to if it is not needed anymore 
    delete abc1 
} 

維基百科有一個very nice article關於堆和棧內存,讓更多關於他們的信息,並提供更多的細節的概念。

+1

非常好謝謝你 –