2010-02-03 145 views
12

假設我有以下snipplet:C++析構函數和調用順序

Foo foo; 
.... 
return bar(); 

現在,不C++標準保證了我吧()將被叫做foo ::〜美孚()之前?或者這是編譯器/實現的選擇?

謝謝!

+0

你的C++教科書對這個主題有什麼看法? – 2010-02-03 23:48:38

+2

你說的這本書是什麼?這是否像堆棧溢出,但編輯,並放在紙上? – anon 2010-02-04 01:03:59

回答

15

這是保證行爲。實際執行展開如下:

0: enter block (scope) 
1: Foo::Foo() 
2. evaluation of bar(); as expression in return statement 
3. save result of the expression as value returned from function 
4. finalize return statement to leave function to its caller (request exit from current scope) 
5: exit block (scope) with call to Foo::~Foo() 

下面是標準的一些參考:

  • 什麼程序執行擔保,一般

1.9程序執行

10具有自動存儲持續時間(3.7.2)的每個對象的實例是 與每個進入其 塊的條目相關聯。

  • foo是自動存儲時間和:

3.7.2自動存儲。

1本地對象明確宣佈自動或註冊或不顯式聲明 靜態或extern具有自動存儲時間。這些對象的存儲會持續到創建它們的塊退出。

  • 什麼是return語句的實際效果

6.6.3 return語句

2(...)表達式的值返回給調用者功能

and

6.6跳轉語句(返程屬於跳躍語句)

2在從範圍出口(但是完成),析構函數(12.4)被稱爲用於與自動存儲持續時間的所有 構造的對象(3.7.2 )

  • 什麼保證的效果產生

6.7聲明陳述

2個變量與塊聲明的自動存儲持續時間 銷燬出口從塊

12.4析構函數

10析構函數被調用隱式地(1)對於具有靜態存儲持續時間的構造的 對象 (3.7.1)at程序終止 (3.6.3),(2)用於構造對象 具有自動存儲持續時間 (3.7.2)當塊在其中 對象被創建出口(6.7)

這是不容易掌握圍繞所有C++標準散佈的單個想法形式細節。希望快速瀏覽會幫助你自己做出這樣的分析。

7

是的,bar()將在foo的析構函數之前被調用。

標準表示: 6.6:「從範圍(但是完成)退出時,析構函數(12.4)是 稱爲用於與自動存儲持續時間 (3.7.2)(命名對象或臨時變量)的所有構造的對象的是在其聲明的相反順序中在該範圍內聲明, 「。

直到返回語句完成後,範圍纔會保留。

5

調用bar()的結果必須在包含Foo的堆棧幀被清除之前進行評估,所以是的,bar()將在Foo ::〜Foo()之前被調用。

3

對象在離開示波器時會被破壞。

return離開範圍,但它不能返回,直到它執行bar()。 Ergo,bar()被調用。

2

想一想,如果是return bar(foo);?那只是工作,並且如果銷燬順序不同,這取決於您是否將該參數作爲參數傳遞,這會很愚蠢。