2010-07-25 133 views
2

比方說,我有一個充當「智能指針」的類,並在銷燬時釋放某種系統資源。構造函數返回值的異常

class Resource{ 
protected: 
    ResourceHandle h; 
public: 
    Resource(ResourceHandle handle) 
    :h(handle){ 
    } 

    ~Resource(){ 
     if (h) 
      releaseResourceHandle(h);//external function, probably from OS 
    } 
}; 

而且我有一些函數返回用於 「資源」 的初始值:

ResourceHandle allocateHandle(); 

現在,如果我這樣做在我的代碼:

Resource resource(allocateHandle()); 

和allocateHandle( )拋出異常,究竟會發生什麼?在Resource()的施工期間或施工前會發生事故嗎?

常識告訴我,因爲在allocateHandle返回之前拋出異常,所以執行甚至不會輸入Resource()構造函數,但我並不完全確定它。這是一個正確的假設嗎?

回答

4

在任何函數調用之前評估參數 - 在本例中爲構造函數 - 。 因此,在構造函數調用之前拋出異常

1

這是一個正確的假設。

0

是的,您的假設是正確的。

此時您只創建參數並將它們推入堆棧。 「資源」的對象甚至沒有形成!

因此,在堆棧展開期間,異常不會調用析構函數。

1

如果編譯器進入構造函數,它會從沒有返回的函數傳入什麼值?

3

是的,你是正確的(正如其他人所說的)。

但你在暗指(我認爲)。
如果輸入構造函數並拋出異常,對象會發生什麼。

析構函數仍然會執行嗎?

如果構造函數實際完成(如果異常是拋出構造函數然後構造函數未完成的throw),則只會觸發析構函數。在這種情況下,構造函數不會被輸入,因此對象不存在,因此析構函數將不會被執行。

如果在構造函數執行時拋出異常,會發生什麼情況。
在這種情況下,因爲構造函數沒有完成,析構函數也不會執行,但是所有成員字段呢?如果通過異常離開構造函數,則所有完全形成的成員將調用它們的析構函數(完全形成的成員是構造函數已被調用併成功完成的成員)。