簡體   English   中英

什么時候在C ++中使用new?

[英]when to use new in C++?

什么是什么時候使用“新”來創建一個類的實例的好政策? 我已經習慣了一段時間編程C ++,但我仍然不確定何時才是這樣做的最佳時機:

MyClass thing(param1, param2);

對此:

MyClass* thing;
thing = new MyClass(param1, param2);

有什么建議?

在設計方面, 盡可能使用自動(堆棧)分配 每當您需要將對象的生命周期延長到某個范圍之外時,就會動態分配它。

即便如此,也絕不動態分配原始內容 始終將它們包裝到某種包裝器中,該包裝器實現了Scope-Bound Resource Management(SBRM,首先以啞/尷尬的名稱資源獲取初始化或RAII而聞名)。也就是說,動態分配應該保存在將要清理的自動對象中自動起來!

一個很好的例子是std::vector :你不能泄漏vector內部的內存,因為它的析構函數在內存應該被釋放的每個場景中運行,並且它將為你釋放它。 auto_ptr是標准庫中第一個也是唯一一個可用的智能指針,但它非常糟糕。 更好的方法是使用shared_ptr ,或Boost和/或TR1和/或C ++ 0x中提供的許多其他流行的智能指針。

性能方面,堆棧上分配的對象可以非常快速地完成(堆棧大小增加了每個函數調用,所以所有需要的內存都是通過簡單的指針移動預先分配的。)相反,動態分配通常需要更多時間。 使用自定義分配方案可以獲得快速的動態分配,但即使是最好的也會比堆棧分配慢。

有時,您可能會發現花費太多時間復制周圍的物體。 在這種情況下,動態分配它並僅僅移動指針可能是值得的。 但是,請注意我說“找到”。 通過剖析和測量,從不猜測,您可以找到這種變化。

所以:盡可能自動分配,需要時動態分配。

第一種方法是在堆棧上創建一個本地實例,當調用函數退出時,該實例就會消失。 第二個創建一個保留在堆上的實例,直到(以及如果)再次顯式釋放它。 選擇取決於您對對象的控制和生命周期。

經驗法則是:如果它沒有new ,不要使用new

通常:如果您計划刪除同一范圍內的對象,則不需要使用new 如果對象非常大,您可能想要使用new
如果您想了解詳細信息,可能需要查看堆和堆棧內存之間的區別。

首先,問問自己這個問題,當另一個函數想要復制對象時,它是否有意義?

如果復制對象是有意義的,那么最好的辦法是在堆棧上創建所有內容或作為成員變量,然后在需要時只傳遞副本。

如果復制對象沒有意義,則需要使用new表單,以便可以安全地將指針傳遞給對象。 您必須使用指針(或引用),因為如上所述,復制對象沒有意義。

我知道有兩個例外:

如果您知道在當前函數完成后將不會使用該對象,則可以在堆棧上創建該對象以便將其刪除。 只是確保之后沒有人抓住它的指針! (我很少發現這種情況,但它發生了)

如果該對象由另一個本身不能被復制的類在內部使用,則可以將其作為成員變量放入。 因為它所在的對象不會被復制,並且它僅供內部使用,這將是安全的。

 MyClass thing(param1, param2); //memory for thing is allocated on the process stack(static allocation)

 MyClass* thing;
 thing = new MyClass(param1, param2); //memory is allocated dynamically on the heap(free store) for thing

不同之處在於:

 int main()
 { 
   {
    MyClass thing(param1, param2); //thing is local to the scope
   } //destructor called for thing
   //cannot access thing (thing doesn't exist)
 } 

 int main()
 {
   {
     MyClass* thing;
     thing = new MyClass(param1, param2);
   }
  //the object pointed to by thing still exists
   //Memory leak
 }  

對於大型對象,您必須動態分配內存(使用new),因為進程堆棧的大小有限。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM