2011-09-19 58 views
2

我在一個大的項目,該模塊主要包括了大量的代碼像讀碼:「捕獲」後關於C++的嘗試-catch

try 
{ 
} 
catch(...) 
{ 
} 

從字面上看,括號,有「...」,在它。不像「異常e」。

這讓我有點擔心。 這種做法是好還是安全? 謝謝。

+0

我想像這是各種各樣的通配符?其他人可以證實嗎? – MGZero

+0

@MGZero,是的,它是一個通配符,它​​捕捉*一切*。 –

+0

複製[C++ try catch practices](http://stackoverflow.com/questions/2967062/c-try-catch-practices) –

回答

11

不,這是一個可怕的做法。

如果你catch(...),你不知道你發現了什麼。它捕獲所有C++異常(並且在某些平臺上使用某些設置,它也捕獲其他異常,例如Visual C++中的結構化異常)。

如果你不知道拋出了什麼異常,你不知道系統的狀態是什麼:你怎麼知道程序是否繼續運行是安全的?

退出catch(...)塊的唯一兩種方法是終止程序或重新拋出異常(使用throw;)。如果在拋出異常但不能依賴析構函數的情況下需要執行一些清理操作,後者有時很有用。

+3

如果你需要做一些清理工作,並使用'throw;完成後重新拋出。當然,使用RAII類會更好。 – bdonlan

+0

@bdonlan:你說的沒錯,我想在你自己編寫一個RAII容器的時候,在某些情況下使用catch(...)會很有用(我不記得曾經做過這,但我想這是可能的)。 –

+0

堆棧展開期間從析構函數拋出的異常終止程序;在RAII容器中,當析構函數中發生異常時顯式中止程序以確保即使您不__正在執行堆棧展開 – bdonlan

1

它捕獲所有異常。看到這個代碼:

try { 
    throw CSomeOtherException(); 
} 
catch(...) { // Handle all exceptions 
    // Respond (perhaps only partially) to exception 
    throw;  // Pass exception to some other handler 
} 

MSDN

你並不需要聲明這個參數;在很多情況下,它可能足以通知處理程序已發生特定類型的例外 。但是,如果您在 異常聲明中未聲明異常對象,則您將無法訪問catch處理子句中的 中的該對象。

沒有操作數的throw-expression會重新拋出當前正在處理的異常 。這樣的表達式應該只出現在捕獲處理程序中的處理程序或函數中。重新拋出的異常對象是原始異常對象(不是 副本)。例如:

希望這有助於!

這種做法是安全的,只有當你有正確的處理程序寫入例外。避免它在我看來更好。

3

catch(...)捕獲全部例外。

通常情況下,你不想這樣做。你不知道你剛剛發現了什麼,如果你離開catch塊,你只是默默地忽略了某種錯誤。這可能會導致以後發生非常糟糕的事情。由於您不知道發生了什麼錯誤,因此您無法從中恢復,因此唯一合理的做法是允許異常繼續(重新拋出異常)或中止程序的執行(請致電abort()或致電abort()exit())。

但是,如果你有一些清理工作需要執行,也可能是合理捕獲所有異常,進行清理,然後再次引發例外:

try { 
    // ... 
} catch (...) { 
    abortTransaction(); 
    throw; 
} 

這就是說,它通常是最好使用所謂的RAII classes自動執行此清理:

DBTransaction txn = db.StartTransaction(); 

// do stuff that may throw; if it throws, txn will be destroyed, 
// and its destructor can abort the transaction 
// As such, an explicit try { } catch(...) { } isn't needed