首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C++ 異常捕獲失效:throw new std::exception() 指針類型不匹配 catch 引用

     編輯:程式設計綜合問答

C++ 異常處理中,throw new std::exception() 拋出的是指針類型(std::exception*),而 catch (std::exception& e) 捕獲的是引用類型,兩者類型不匹配,導致異常穿透至 catch(...),輸出 "why???"。

錯誤代碼

try {
    throw new std::exception();  // 拋出指針
} catch (std::exception& e) {    // 捕獲引用,類型不匹配
    std::cout << "ok";
} catch (...) {
    std::cout << "why???";  // 實際執行這裡
}

正確寫法(三種等價形式)

1. 拋出對象,捕獲引用(標準做法)

try {
    throw std::exception();  // 無 new,拋出臨時對象
} catch (const std::exception& e) {  // const 引用延長生命周期
    std::cout << "ok: " << e.what();
}

2. 拋出指針,捕獲指針(不推薦,需手動 delete)

try {
    throw new std::exception();
} catch (std::exception* e) {
    std::cout << "ok: " << e->what();
    delete e;  // 必須釋放,否則內存洩漏
}

3. 拋出智能指針(現代 C++)

try {
    throw std::make_shared();
} catch (const std::shared_ptr& e) {
    std::cout << "ok: " << e->what();
}

核心規則

  • 拋出類型必須與捕獲類型精確匹配(含 cv 限定、引用/指針/值語義)。
  • 標準庫異常類設計為值語義拋出,引用捕獲,切勿使用 new。
  • catch(...) 為最後兜底,僅用於日誌記錄後重拋(throw;)或安全關閉。

編譯器提示

現代編譯器(GCC/Clang/MSVC 高警告級)會對 throw new Exception 發出警告:throwing a pointer to a temporary object 或 catch handler type mismatch。

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