2014-09-10 131 views
3

在下面的代碼中,我使用一個包裝對象臨時存儲來自內存中的數據庫的一些東西。我的問題很簡單:如果函數返回提前或拋出異常,是否會調用對象的析構函數?

我可以確定析構函數被調用嗎?我特別擔心的是 a)testCondition爲真,並且函數早期從構造tempObj的作用域的內部作用域返回 b)在執行此函數期間發生了一些運行時錯誤(捕捉到更高級)

(作爲一個方面的問題:這是暫時存儲一些數據在我的應用程序的好方法,someFunc()是保存/當前數據庫的導出功能)

class TempStore 
{ 
public: 
    TempStore() {/* delete some stuff from a db and store this in memory*/} 
    ~TempStore() {/* write this stuff back into the db*/} 
}; 

void someFunc(bool testCondition) 
{ 
    TempStore tempObj = TempStore(); 
    // some code 
    if (testCondition) 
     return; //early return 
    // some more code 
} 
+0

您是否嘗試添加日誌(例如printf或寫入文件)並進行調試?在你顯示的代碼中,析構函數將被調用。 – 2014-09-10 14:55:48

+1

運行時錯誤是什麼意思? C++異常?然後它會工作。如果你的程序真的失敗了,seg故障等,那麼它將無法工作。 – mkaes 2014-09-10 14:57:12

+1

是的,當'someFunc()'函數返回時,假定「正常」程序執行(*例如*沒有崩潰或分段錯誤),'TempStore'的析構函數將被調用。這被稱爲[「資源獲取初始化」(RAII)習語](https://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization),它是現代C++的基石。 – 2014-09-10 15:02:05

回答

6

當程序離開對象的作用域時,自動對象的析構函數將被調用。這包括從函數返回(提前或以其他方式),並通過異常退出 - 只要異常得到處理。在例外的情況下,在處理異常之前在堆棧展開期間調用它。

它可能不能被稱爲在某些情況下,包括:

  • 通過以longjmp呼叫離開;這給出了未定義的行爲;
  • 通過未處理的異常離開;沒有說明棧是否展開。
  • 終止程序(例如呼叫exit,或產生導致終止的信號)。
2

是,析構函數將被調用。如果您提前返回,每個在堆疊上創建的對象都將被正確銷燬。如果拋出異常,析構函數將在程序執行到達catch塊後調用。

+2

這個答案是不完整的,因此是錯誤的。從標題:「如果函數崩潰,將調用對象的析構函數嗎?「 – 2014-09-10 15:01:10

+1

我認爲他說的是異常而非崩潰 – nikitoz 2014-09-10 15:02:40

+0

即使是例外情況,如果代碼沒有在try塊中運行,也不會發生這種情況。 – juanchopanza 2014-09-10 15:02:50

2

將會調用析構函數,除非程序由於seg故障或停電等原因而爆炸。只是簡單地從一個函數返回或拋出一個異常不足以阻止析構函數的運行。

儘管這個設計有點不對,因爲寫入數據庫是一種可能失敗的操作,並且從析構函數中拋出異常是一個非常糟糕的主意。

+0

您能否建議我如何處理這種情況?如果從析構函數中拋出異常會發生什麼? – 2014-09-10 15:11:41

相關問題