這是一個基本的例子在堆或堆棧中創建構造函數的區別是什麼?
myclass * abc = new myclass()
和
myclass abc
的區別是什麼?在這兩種情況下,堆棧中創建的對象是abc
?如果對象是在堆中創建的,有什麼不同?
從答案,我採取這一(請編輯如果不正確):如果我們要當它是出於沒有刪除類的變量
構造函數初始化類(成員)
範圍,我們應該把對象創造堆起來。
這是一個基本的例子在堆或堆棧中創建構造函數的區別是什麼?
myclass * abc = new myclass()
和
myclass abc
的區別是什麼?在這兩種情況下,堆棧中創建的對象是abc
?如果對象是在堆中創建的,有什麼不同?
從答案,我採取這一(請編輯如果不正確):如果我們要當它是出於沒有刪除類的變量
構造函數初始化類(成員)
範圍,我們應該把對象創造堆起來。
儘管在例abc
是在自動存儲器(通常稱爲「堆」)是不相同的種類的對象:
abc
是一個指針,它被存儲在堆棧中。但是,存在存儲在動態存儲器(通常稱爲「堆」)中的myclass
類型的第二個對象。對象指針abc
指向堆中的對象。abc
的類型爲myclass
。這是創建的唯一對象。這兩種方法之間主要區別在於,在動態存儲器中創建一個對象可以「活得比」在其內部的被創建它的功能。當指針abc
超出範圍時,其堆對象保持活動狀態。例如,您可以在不進行復制的情況下從函數中返回它。
@StelTeam你將通過一個指針訪問你的對象,這是一種不同的語法。您需要通過調用delete來手動刪除對象。 – dasblinkenlight
謝謝你的幫助我如此多 –
和1件事情如果指針超出範圍,那麼我如何訪問該對象? –
在myclass * abc = new myclass();
中,您創建了一個指向棧上myclass的指針和堆上myclass的實例。在myclass abc;
中,您將在堆棧上創建myclass的實例。
有很多不同之處,但最直接的一點是當堆留在當前離開當前上下文(例如從函數返回)時釋放堆棧。因此,在第一個示例中,myclass的實例將保留在內存中,直到您手動釋放它爲止;而在第二個選項中,當您退出其寫入的函數或代碼塊時,它將自動清除。
從構造函數調用的角度來看,兩者基本沒有區別。在這兩種情況下,都會調用類的默認構造函數來構建對象。只是在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關於堆和棧內存,讓更多關於他們的信息,並提供更多的細節的概念。
非常好謝謝你 –
你的意思是除了對象存儲在不同的地方?而且你需要一個指向堆分配對象的指針?也許你可以詳細闡述什麼是困擾你或者你在想什麼? –
而且你需要(手動)管理使用'new'分配的對象的銷燬(而另一個會在其生命週期結束時自動銷燬) – UnholySheep
我的意思是在這兩個代碼中,對象abc是在堆棧右側創建的?如何在堆中創建構造函數可以影響代碼? –