2011-08-10 33 views
3
try 
{ 
    range_error r("Hi I am hereeeee!"); 
    cout << r.what() << endl; // print "Hi I am hereeeee!" // case one 
    exception *p2 = &r; 
    cout << p2->what() << endl; // print "Hi I am hereeeee!" // case two 
    throw p2; 
} 
catch (exception *e) 
{ 
    cout << e->what() << endl; // print "Unknown exception" // case three 
} 

問題>C++ - 爲什麼'什麼'在捕獲範圍內打印「未知異常」?

我不知道爲什麼的情況下三版「未知異常」,而不是「你好我是hereeeee!」? 打印結果複製自VS2010

+0

爲什麼這會降低選票?由我投票。 – john

回答

5

該程序導致未定義的行爲。因爲變量rtry塊中被聲明爲,所以在調用catch處理程序之前,它將超出範圍。此時,e指向棧中的某個區域,其中range_error的對象用於存在。

下面的程序應該打印的預計業績:

range_error r("Hi I am hereeeee!"); 
try 
{ 
    cout << r.what() << endl; // print "Hi I am hereeeee!" // case one 
    exception *p2 = &r; 
    cout << p2->what() << endl; // print "Hi I am hereeeee!" // case two 
    throw p2; 
} 
catch (exception *e) 
{ 
    cout << e->what() << endl; // print "Hi I am hereeeee!" // case three 
} 

但是,你不應該拋出一個指向一個對象,你應該拋出對象本身。運行時庫將存儲range_error對象的副本並將該副本傳遞給異常處理程序。

因此,你應該使用下面的代碼來代替:

try 
{ 
    range_error r("Hi I am hereeeee!"); 
    cout << r.what() << endl; // print "Hi I am hereeeee!" // case one 
    throw r; 
} 
catch (const exception& e) 
{ 
    cout << e.what() << endl; // print "Hi I am hereeeee!" // case two 
} 
+0

我應該自己沒有發現這個問題。謝謝 – q0987

+0

Jeez,你**必須**已經複製了我,除非你的回答更好。 – john

+0

@John:除此之外,我也先發布了,並在'catch'塊中修復了註釋;-) –

3

因爲當你到達catch時,你的range_error已被破壞,你正在捕捉一個懸掛指針。或者將range_error聲明移到try塊之外,或者更好地拋出一個實例並通過引用來捕獲。

1

由於所指向的異常對象已經你捕捉到了異常的時間超出範圍。如果你寫了

range_error r("Hi I am hereeeee!"); 
try 
{ 
    cout << r.what() << endl; // print "Hi I am hereeeee!" // case one 
    exception *p2 = &r; 
    cout << p2->what() << endl; // print "Hi I am hereeeee!" // case two 
    throw p2; 
} 
catch (exception *e) 
{ 
    cout << e->what() << endl; // print "Unknown exception" // case three 
} 

它會打印你的預期。

相關問題