我目前在 C 14 中有如下代碼:
try {
// create objects, process input
myObject obj; // may throw std::invalid_argument in constructor
for (i = 0; i < n_files; i )
{
try {
process_file(); // may throw std::invalid_argument and std::runtime_error()
}
catch (std::exception& e)
{// print error
continue;
}
}
catch (std::exception& e)
{// print error
return 0;
}
對于我自己的函式,我只是拋出 std::runtime_error 和 std__invalid_exception 之類的 std 例外。
這個想法是,在外部 try 塊中創建的物件應該拋出例外并被外部 catch 塊捕獲,然后結束程式。process_file() 拋出的例外將被內部 try 塊捕獲,它只會列印一些錯誤但不會導致程式終止,并且程式將繼續處理下一個檔案。
外部 try 塊包含物件建構式呼叫,然后將在內部 try-catch 中使用這些呼叫,因此我不能簡單地將其移動到它自己的 try-catch 中,否則物件將在回圈中未定義。
但是根據我的理解,這段代碼無法正常作業,因為在外部 try 塊中拋出的例外將首先命中內部 catch 陳述句,因為這是代碼中可到達的第一個 catch 陳述句。此外,像這樣嵌套的 try-catch 將是不好的形式/從我讀過的內容中讀取內容會令人困惑。
這樣做的正確方法是什么?謝謝!
uj5u.com熱心網友回復:
根據我的理解,此代碼無法正常作業
是的,對于您描述的場景,它會作業得很好。
在外部 try 塊中拋出的例外將首先命中內部 catch 陳述句,因為這是代碼中可到達的第一個 catch 陳述句。
那是不正確的。這不是關于代碼中的順序,而是范圍中的順序。try如果外部try拋出,則內部不在范圍內。例外沿著呼叫堆疊向上,從當前作用域開始,然后是它最近的外部作用域,然后是下一個外部作用域,依此類推,直到找到匹配的catch. 例如:
try {
// if any std exception is thrown here, jumps to A below...
try {
// if std::invalid_argument is thrown here, jumps to B below...
// if any other std exception is thrown here, jumps to A below...
for (int i = 0; i < n_files; i)
{
try {
// if any std exception is thrown here, jumps to C below...
}
catch (std::exception& e) // C
{
// print error
continue;
}
}
// if std::invalid_argument is thrown here, jumps to B below...
// if any other std exception is thrown here, jumps to A below...
}
catch (invalid_argument& e) // B
{
// print error
return 0;
}
}
catch (exception& e) // A
{
// print error
return 0;
}
像這樣嵌套的 try-catch 將是不好的形式/從我讀過的內容中讀取。
這也是不對的。使用嵌套try塊沒有錯。
然而,在這個例子中,只有內部try捕獲更有意義,具體來說,因為這是它期望并愿意忽略的兩種型別以繼續回圈。一般不要在那個地方抓。這樣,如果拋出一些意外(例如),那么外部應該處理它以終止行程。 std::invalid_argumentstd::runtime_errorstd::exceptionprocess_file()std::bad_alloccatch
try {
// if any std exception is thrown here, jumps to A below...
try {
// if std::invalid_argument is thrown here, jumps to B below...
// if any other std exception is thrown here, jumps to A below...
for (int i = 0; i < n_files; i)
{
try {
// if std::invalid_argument is thrown here, jumps to D below...
// if std::runtime_error is thrown here, jumps to C below...
// if any other std exception is thrown here, jumps to A below...
}
catch (std::invalid_argument& e) // D
{
// print error
continue;
}
catch (std::runtime_error& e) // C
{
// print error
continue;
}
}
// if std::invalid_argument is thrown here, jumps to B below...
// if any other std exception is thrown here, jumps to A below...
}
catch (invalid_argument& e) // B
{
// print error
return 0;
}
}
catch (exception& e) // A
{
// print error
return 0;
}
設計 a 的最佳方法catch是讓它只捕獲它知道如何在代碼中的那個位置處理的特定型別的例外。讓外部catch處理一切。如果拋出例外并且沒有catch找到可以處理它的匹配項,則默認情況下該行程將終止。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/324099.html
