首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

C++ 異常處理完整指南:throw 規格、三種傳遞方式與最佳實踐

     編輯:C++ 入門

異常處理是 C++ 建構健壯軟體的核心機制。本文系統解析 throw 例外規格、三種異常傳遞方式(傳值、傳指標、傳參考)的優劣對比、多型行為差異、記憶體管理陷阱,並給出現代 C++ 異常處理最佳實踐建議。

throw 例外規格


void f() throw();           // 不拋出任何異常(異常安全)
void f() throw(...);        // 可拋出任意異常
void f() throw(MyException); // 僅拋出 MyException 類型

注意:C++11 起 throw() 棄用,改用 noexcept;動態例外規格 C++17 移除。現代代碼請使用 noexcept / noexcept(expr)。

三種異常傳遞方式深度對比

1. 傳值 —— 物件切割與多型失效


class MyException : public exception {
    virtual const char* what() const throw() { return "myException"; }
};
void f() { throw MyException(); }
try { f(); }
catch (exception exc) { cout << exc.what(); }  // 輸出 "Unknown exceptions"

問題:catch (exception exc) 觸發拷貝建構,衍生類別特有資訊被切割,呼叫基類 what() 而非衍生類別覆寫版本。不可用於多型異常體系。

2. 傳指標 —— 多型可行但記憶體管理惡夢


void f() { throw new MyException(); }
try { f(); }
catch (exception* p) { cout << p->what(); delete p; }

優點:保持多型,正確呼叫衍生類別 what()。

缺點:

  • 拋出堆疊物件位址 → 懸空指標
  • 拋出 new 物件 → 何時 delete?catch 區塊?若重拋?若未捕獲?極易洩漏或雙重釋放

3. 傳參考 —— 最佳實踐


void f() { throw MyException(); }
try { f(); }
catch (exception& exc) { cout << exc.what(); }

優勢:

  • 無拷貝,無切割,完整保持多型
  • 無記憶體管理負擔,異常物件由執行期自動管理生命週期
  • 效能最佳,語法最簡潔

現代 C++ 異常處理鐵律

  1. 拋出:throw MyException();(值語義,非指標)
  2. 捕獲:catch (const BaseException& e)(const 參考,支援多型)
  3. 異常類別:繼承 std::exception,覆寫 what()
  4. 資源安全:RAII 確保異常拋出時資源正確釋放
  5. 不濫用:異常用於「異常狀況」,非正常流程控制
  6. noexcept:標記不拋出函式,啟用編譯器優化

異常安全等級

  • 基本保證:不洩漏資源,物件保持有效狀態
  • 強烈保證:操作失敗時狀態回滾(交易語意)
  • 不拋出保證:noexcept,絕不拋出異常

總結

「以值拋出,以 const 參考捕獲」是 C++ 異常處理的黃金法則。它同時解決多型保持、物件切割、記憶體管理、效能四大核心問題。配合 RAII、noexcept、標準異常體系,能構建工業級異常安全程式碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved