2013-08-23 68 views
0
void fun() 
{ 
    A *a = new A; //Here A is a class 
}     //a should be deleted in fun()'s scope 

int main() 
{ 
    fun(); 
    return 0; 
} 

創建的對象存在於免費商店中,並且不能由main()函數使用。爲什麼應該在免費商店創建對象。是的,我們可以將對象引用傳遞給主函數,但我們甚至可以傳遞對象的副本(即使未使用新運算符創建時)。那麼新的和刪除操作符的確切用法是什麼?在免費商店中創建對象有什麼用處?

+2

因爲免費商店有更多的自由空間 – billz

+0

我認爲這是免費商店(堆)存在的唯一原因 - 理論上分配的內存與通過RAM可用。 –

+0

@ManojAwasthi不止於此。儘可能多地爲當前內存模型尋址內存,具體取決於您擁有多少虛擬存儲。 4GB 32位地址空間可以在現代系統上輕鬆訪問。 (64bit,heh,不太容易=) – WhozCraig

回答

3

在你的例子中,沒有,並且 使用動態分配是不好的做法。當對象 具有標識(或由於某些其他原因不能被複制)時使用動態分配,並且對象的生存期不爲而不是對應於某些 預定的生存期,如靜態或自動。動態 分配也可能在一些情況下使用,其中複製 昂貴,並且分析器顯示覆制是 的一個瓶頸;在這種情況下,使用動態分配和複製指針可能會消除瓶頸。 (但是這應該是 直到配置文件顯示它必要時纔會完成。)

6

簡答:在運行時分配內存。

欲瞭解更多信息,請考慮:http://www.cplusplus.com/doc/tutorial/dynamic/

+5

我不敢相信我會投票給一個有clinkplus.com網站鏈接的答案。有人阻止我。 – WhozCraig

+0

我感到內疚;) – Sambuca

+1

@Sambuca你應該!你把這個邪惡帶到這個......和平論壇。就是這樣......呃,我警告你!不要再這樣做! :p –

1

好問題。通常,這不是必要的 - 明確。當然,還有另一個回答說「在運行時分配內存」以及類似的評論。但你可以通過std::vector<>std::string等實現。他們會在正確的時刻爲你做幕後的所有記憶。

這就是new/delete的原因之一 - 實現某些類很有用。

您提到可以傳遞對象的副本。這可能有點貴,所以爲了優化目的,用new/delete替換最昂貴的副本是值得的。有一些稱爲「分析器」的工具可用於識別哪些副本很昂貴。

第三個原因是多態性。你可能有類似於Base* ptr = (foo>7) ? new Derived1 : new Derived2(foo);的代碼,你不知道你將需要什麼對象,它應該如何表現。由於Derived1Derived2的大小通常是不相關的,因此只能在運行時知道需要多少內存。

0

重要的原因是stack是如何工作的。它只有推送和流行操作。在釋放之後的所有內容之前,您無法釋放堆棧中的內容。換句話說,如果函數返回時從棧中釋放了某些東西(例如函數調用的堆棧框架),則堆棧上方的所有內存也將被釋放(並且您最好確保它正確地被破壞,請參閱下面的內容)。

程序通常需要存儲獨立於堆棧的數據。有兩種方法:在編譯時分配內存,如static data,或在free store, also called heap中分配內存。

當然有可能有多個堆棧,事實上,這通常也可以在方便且有用的情況下完成。但它是通過使用堆棧容器變量完成的,其類型如std::stack,然後將其用作僅用於數據的額外堆棧。通用處理器體系結構每個進程/線程只有一個「本地」堆棧,用於函數調用和堆棧變量,這些額外的堆棧總是由程序代碼分離和創建的,只是普通的數據結構與列表,地圖等相同。


關於你的問題的代碼,這一點要提出的是,在現代C++裸new一般是令人難以接受的。您應該使用RAII mechansim如智能指針:

void fun() 
{ 
    auto a = std::unique_ptr<A>{ new A }; // C++11 syntax 
    // object is automatically destroyed when a goes out of scope, no leak 
    // note: heap should be used like this only if there's a reason, including: 
    // - A is big, and might conceivably overflow the stack 
    // - ownership of object may get moved and outlive the unique_ptr 

}   

和具體問題「存在於自由存儲創建的對象,不能由main()函數中使用的,爲什麼要的對象是在免費商店中創建。「,好吧,在問題代碼中,它不應該在免費商店中創建,沒有理由。它應該只是簡單的自動變量,當它超出範圍時會自動被破壞。

+1

你的第二點是完全錯誤的。在很多動態分配合適的情況下,直接使用'new'不一定是問題。你的代碼是濫用'new'(不應該動態分配對象開始)和濫用'auto'的一個很好的例子:如果有使用'new'和'unique_ptr'的有效動機,像'std :: unique_ptr a(new A);'(或'std :: unique_ptr a {new A};')會更好。 –

+0

@JamesKanze一個鏈接,其中包括'auto a = ...'語法的討論:http://herbsutter.com/2013/08/12/gotw-94-solution-aaa-style-almost-always-auto/ – hyde