2011-06-20 35 views
3
#include <iostream> 
#include <exception> 
using std::cout; 
using std::endl; 
class test 
{ 
public: 
    test() 
    { 
     cout<<"constructor called"<<endl; 
    } 
    ~test() 
    { 
     cout<<"destructor called"<<endl; 
    } 
    void fun(int x) 
    { 
     throw x; 
    } 
}; 

int main() 
{ 
    try 
    { 
     static test k;   
     k.fun(3); 
    } 
    catch(int k) 
    { 
     cout<<"exception handler"<<endl; 
    } 
} 

當引發異常時,然後在堆棧展開過程中,我認爲只有本地對象被銷燬,而不是靜態或堆對象。如果這是真的,我不知道爲什麼類(測試)析構函數被調用?謝謝。當引發異常時,是靜態對象還是本地對象?

回答

4

測試析構函數在主退出後調用。

catch(int k) 
    { 
     cout<<"exception handler"<<endl; 
    } 
    // Added this line 
    std::cout << "Main Exiting\n"; 
} 

立即測試

> g++ test.cpp 
> ./a.out 
constructor called 
exception handler 
Main Exiting 
destructor called 

靜態(靜態存儲持續時間的對象)被破壞在創作主退出後的順序相反。

0

析構函數被調用是因爲你的程序正在退出。只有自動存儲持續時間的對象(絕對不是堆棧對象或堆對象)被銷燬。

+0

你的意思是「...靜態對象或堆對象」 –

0

運行此代碼,我得到的輸出

constructor called 
exception handler 
destructor called 

這是合理的。首先調用靜態test對象的構造函數。當引發異常時,它被異常處理程序捕獲並且打印消息。最後,當程序終止時,調用靜態對象test的析構函數。

異常只會導致具有自動持續時間(即本地)的變量的生命週期結束,假設異常實際上被捕獲到某處。異常不會破壞具有動態持續時間的對象(即分配爲new的對象),但如果在動態分配對象的構造函數中發生異常,內存將被回收,因爲否則無法取回內存。同樣,static對象不會被銷燬,因爲它們應該持續用於整個程序。如果它們被清理乾淨,如果在程序中傳遞了這些對象的引用,可能會導致問題。

希望這會有所幫助!

+0

是的,你是對的,但如果動態地分配內存的構造器中發生異常,那麼不需要回收內存,因爲如果構造器沒有完全構建,它不打算刪除。 – Alok