簡體   English   中英

為什么不對要返回的對象調用析構函數?

[英]Why doesn't the destructor get called on objects you are returning?

因此,據我了解,您可以通過返回指向C ++的指針來返回對象。 但是我給人的印象是,一旦函數運行完畢,析構函數將在所有對象上調用。 為什么不對要返回的對象調用析構函數?

當那些對象離開其作用域時,僅調用具有自動存儲持續時間的對象的析構函數(不僅僅是函數,而是任何作用域:大括號, for語句,甚至單行表達式)。

另一方面, 靜態存儲持續時間的對象僅在程序退出時銷毀,而動態存儲持續時間的對象(即使用new運算符創建的對象)僅在您的請求下被手動銷毀。

當您以描述的方式返回指針時,幾乎可以肯定該指針指向動態創建的對象,因此,指針的接收者有責任確保最終清除該對象。 這是裸指針的最大缺點:它們不傳遞任何隱式的所有權聲明,並且您必須在代碼外部手動提供有關誰負責動態對象的信息。

使用new創建的對象的析構函數只有在delete指針后才會被調用。

為了確保您不會忘記刪除指針,請嘗試使用智能指針,例如std::shared_ptrstd::unique_ptr

如果您的編譯器不夠新穎,無法包含智能指針,則可以從Boost中找到一些內容。

當您返回對對象的引用時,該引用將不再作用於函數,因此不會隨函數失效(即,不會刪除指向對象的指針)。

僅當您錯誤編寫代碼時,才會發生這種情況。 例如:

Foo* MyFunction()
{
    Foo foo(2);
    return &foo;
} // foo is implicitly destroyed as we return

這已破了。 我使用foo的地址,但是由於超出范圍,它也被破壞了。 這可以:

Foo* MyFunction()
{
    Foo* j=new Foo(2);
    return j;
} // j is implicitly destroyed as we return

這可以。 盡管j由於超出范圍而被銷毀,但我返回的值仍然是我創建的Foo的地址。 我分配的foo不會被銷毀,因為它不會超出范圍。

有兩種分配對象的方法:堆棧和堆。

1)使用new關鍵字在堆上創建對象。 這些對象在被delete之前不會被破壞d。

2) 堆棧上還存在其他對象-沒有new ,也沒有delete 這些對象超出范圍時將被銷毀。 如果您返回指向這些對象之一的指針(通過獲取堆棧分配的對象的地址,則一旦該對象超出范圍,該指針將無效。

C ++(。net外部)在您告知對象之前不會刪除對象。

暫無
暫無

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

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