異常與捕獲

1.C++ 異常概念

異常是一種處理錯誤的方式,當一個函數發現自己無法處理的錯誤時就可以拋出異常,讓函數的直接或間接的調用者處理這個錯誤。

  • throw:當問題出現時,程序會拋出一個異常。這是通過使用?throw?關鍵字來完成的。
  • catch:在您想要處理問題的地方,通過異常處理程序捕獲異常。catch?關鍵字用于捕獲異常,可以有多個?catch?進行捕獲。
  • trytry?塊中的代碼標識將被激活的特定異常,它后面通常跟著一個或多個?catch?塊。

如果有一個塊拋出一個異常,捕獲異常的方法會使用?try?和?catch?關鍵字。try?塊中放置可能拋出異常的代碼,try?塊中的代碼被稱為保護代碼。

2. 異常的拋出和捕獲

異常的拋出和匹配原則
  1. 異常是通過拋出對象而引發的,該對象的類型決定了應該激活哪個?catch?的處理代碼。
  2. 被選中的處理代碼是調用鏈中與該對象類型匹配且離拋出異常位置最近的那一個。
  3. 拋出異常對象后,會生成一個異常對象的拷貝,因為拋出的異常對象可能是一個臨時對象,所以會生成一個拷貝對象,這個拷貝的臨時對象會在被?catch?以后銷毀。(這里的處理類似于函數的傳值返回)
  4. catch(...)?可以捕獲任意類型的異常,問題是不知道異常錯誤是什么。
  5. 實際中拋出和捕獲的匹配原則有個例外,并不都是類型完全匹配,可以拋出的派生類對象,使用基類捕獲,這個在實際中非常實用,我們后面會詳細講解這個。
在函數調用鏈中異常棧展開匹配原則
  1. 首先檢查?throw?本身是否在?try?塊內部,如果是再查找匹配的?catch?語句。如果有匹配的,則調到?catch?的地方進行處理。
  2. 沒有匹配的?catch?則退出當前函數棧,繼續在調用函數的棧中進行查找匹配的?catch
  3. 如果到達?main?函數的棧,依舊沒有匹配的,則終止程序。上述這個沿著調用鏈查找匹配的?catch?子句的過程稱為棧展開。所以實際中我們最后都要加一個?catch(...)?捕獲任意類型的異常,否則當有異常沒捕獲,程序就會直接終止。
  4. 找到匹配的?catch?子句并處理以后,會繼續沿著?catch?子句后面繼續執行。

代碼展示

void exe()
{throw 1;
}
void func()
{int x = 2, y = 0;auto ret = [=]()->int {if (y == 0) { throw " 除0錯誤"; } else { return x / y; }};std::cout << ret() << std::endl;
}
int main()
{try{func();exe();}catch (const char*tsr){cerr <<tsr << endl;}catch (...){cerr << "未知異常!" << endl;}return 0;
}

下面展示上面的代碼進階版也就是,當你捕獲到異常進行緊急修復,然后重新拋出!重新拋出的異常會被調用鏈上層捕捉!切記這個調用鏈是給上走的!

void exe() {throw 1;
}void func() {int x = 2, y = 0;auto ret = [=]()->int {if (y == 0) {// 拋出標準異常類型,便于統一處理throw std::runtime_error("除0錯誤");} else {return x / y;}};try {std::cout << ret() << std::endl;} catch (const std::runtime_error& e) {std::cerr << e.what() << std::endl;// 修復除零錯誤,將除數修改為非零值y = 1;auto newRet = [x, y]()->int { return x / y; };std::cout << "修復后結果: " << newRet() << std::endl;// 重新拋出異常throw;}
}int main() {try {func();exe();} catch (const std::runtime_error& e) {std::cerr << "main函數捕獲到重新拋出的異常: " << e.what() << std::endl;std::cout << "異常已在下層函數修復,程序繼續執行" << std::endl;} catch (int e) {std::cerr << "捕獲到異常: " << e << std::endl;// 這里可以添加對異常值為 1 的具體處理邏輯std::cout << "異常已處理,程序繼續執行" << std::endl;} catch (...) {std::cerr << "未知異常!" << std::endl;}return 0;
}    

3.繼承拋異常


//
//在實際當中有一個拋出和捕獲特例而且也非常常用!可以拋出派生類對象,讓基類去捕獲
#include <iostream>
#include <thread>
#include <chrono>
#include <cstdlib>
#include <ctime>
#include <string>// 假設存在基類 Exception,這里未給出完整定義,實際需包含相關頭文件或完整實現
void SQLMgr();
//公司常用的異常繼承體系!
class Exception 
{
public:Exception(const std::string& errmsg, int id) : _errmsg(errmsg), _id(id) {}virtual std::string what() const = 0;
protected:std::string _errmsg;int _id;
};class HttpServerException : public Exception {
public:HttpServerException(const std::string& errmsg, int id, const std::string& type): Exception(errmsg, id), _type(type) {}virtual std::string what() const override {std::string str = "HttpServerException:";str += _type;str += ":";str += _errmsg;return str;}
private:const std::string _type;
};class CacheException : public Exception {
public:CacheException(const std::string& errmsg, int id): Exception(errmsg, id) {}virtual std::string what() const override {std::string str = "CacheException:";str += _errmsg;return str;}
};class SqlException : public Exception {
public:SqlException(const std::string& errmsg, int id, const std::string& sql): Exception(errmsg, id), _sql(sql) {}virtual std::string what() const override {std::string str = "SqlException:";str += _errmsg;str += "->";str += _sql;return str;}
private:const std::string _sql;
};void CacheMgr() {srand(time(0));if (rand() % 5 == 0) {throw CacheException("權限不足", 100);}else if (rand() % 6 == 0) {throw CacheException("數據不存在", 101);}SQLMgr();
}void HttpServer() {srand(time(0));if (rand() % 3 == 0) {throw HttpServerException("請求資源不存在", 100, "get");}else if (rand() % 4 == 0) {throw HttpServerException("權限不足", 101, "post");}CacheMgr();
}void SQLMgr() {srand(time(0));if (rand() % 7 == 0) {throw SqlException("權限不足", 100, "select * from name = '張三'");}//throw "xxxxxx";
}int main() {while (1) {std::this_thread::sleep_for(std::chrono::seconds(1));try {HttpServer();}catch (const Exception& e) //捕獲父類對象{std::cout << e.what() << std::endl;}catch (...) {std::cout << "Unkown Exception" << std::endl;}}return 0;
}

4.異常安全

5.庫里面的異常:

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/76036.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/76036.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/76036.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2025年最新自動化/控制保研夏令營預推免面試真題分享(東南大學蘇州校區/華東理工/南航/天大)

筆者來2021級本科自動化專業&#xff0c;以下部分將介紹我在夏令營以及預推免期間發生經歷和問題 東南大學蘇州校區蒙納士大學聯培 東南大學蘇州校區的項目算是一個比較小眾的項目&#xff0c;是第一年在蘇州校區&#xff0c;二三年到南京校區找導師&#xff08;不提供住宿自…

【SQL】MySQL基礎2——視圖,存儲過程,游標,約束,觸發器

文章目錄 1. 視圖2. 存儲過程2.1 創建存儲過程2.2 執行存儲過程 3. 游標4. 約束4.1 主鍵約束4.2 外鍵約束4.3 唯一約束4.4 檢查約束 5. 觸發器 1. 視圖 視圖是虛擬的表&#xff0c;它是動態檢索的部分。使用視圖的原因&#xff1a;避免重復的SQL語句&#xff1b;使用表的部分而…

OGG故障指南:OGG-01163 Bad column length (xxx) specified for column

報錯 OGG-01163 Bad column length (xxx) specified for column AAA in table OWNER.TABLE, maximum allowable length is yyy原因 源端修改了字段長度。 雖然源端和目標端的長度已經通過DDL語句修改到一致&#xff0c;在extract進程未重啟的情況下&#xff0c;生成的trail文…

Linux進程狀態補充(10)

文章目錄 前言一、阻塞二、掛起三、運行R四、休眠D五、四個重要概念總結 前言 上篇內容大家看的云里霧里&#xff0c;這實在是正常不過&#xff0c;因為例如 寫實拷貝 等一些概念的深層原理我還沒有講解&#xff0c;大家不用緊張&#xff0c;我們繼續往下學習就行&#xff01;&…

信息學奧賽一本通 1609:【例 4】Cats Transport | 洛谷 CF311B Cats Transport

【題目鏈接】 ybt 1609&#xff1a;【例 4】Cats Transport 洛谷 CF311B Cats Transport 【題目考點】 1. 動態規劃&#xff1a;斜率優化動規 【解題思路】 解法1&#xff1a;設a點的前綴和 輸入的 d d d序列是從 d 2 d_2 d2?到 d n d_n dn?&#xff0c;共n-1個數字。人…

bluecode-20240913_1_數據解碼

時間限制&#xff1a;C/C 1000MS&#xff0c;其他語言 2000MS 內存限制&#xff1a;C/C 256MB&#xff0c;其他語言 512MB 難度&#xff1a;困難 數據解碼 指定有一段經過編碼的二進制數據&#xff0c;數據由0個或多個"編碼單元"組成。"編碼單元"的編碼方式…

接口自動化進階 —— Pytest全局配置pytest.ini文件詳解!

pytest.ini 是 Pytest 的全局配置文件&#xff0c;用于自定義測試運行的行為和規則。通過配置 pytest.ini&#xff0c;可以避免在命令行中重復輸入參數&#xff0c;提升測試的效率和一致性。 1. 配置文件的位置和格式 位置&#xff1a;pytest.ini 文件通常放在項目的根目錄下。…

ModuleNotFoundError: No module named ‘demjson‘

錯誤 ModuleNotFoundError: No module named demjson 表明 Python 無法在其環境中找到名為 demjson 的模塊。demjson 是一個第三方庫&#xff0c;用于在 Python 中編碼和解碼 JSON 數據。如果你嘗試導入它但遇到了這個錯誤&#xff0c;那很可能是因為你的 Python 環境中沒有安裝…

1、C51單片機(STC8G2K64S4)串口實驗

一、串口1接線圖 1、下面是單片機外接電路圖&#xff0c;P30,P31分別用于RXD和TXD功能引腳 2、我們來查看單片機手冊 串口1需要設置的寄存器 串口1的功能腳配置選擇位&#xff0c;看電路圖選擇的是P3.0,P3.1。 3、串口1&#xff1a;SCON控制寄存器 設置為0x50:0101 0000。&a…

3PL EDI:SA Piper Logistics EDI需求分析

SA Piper Logistics成立于2005年&#xff0c;是一家專注于全球供應鏈管理的第三方物流服務商&#xff08;3PL&#xff09;&#xff0c;總部位于美國芝加哥。公司以“優化物流效率&#xff0c;重塑供應鏈價值”為使命&#xff0c;提供倉儲管理、運輸規劃、訂單履行及跨境清關等一…

vscode正則表達式使用

小標題 ^\d.\d.\d\s.*$ ^表示匹配字符串的開頭。\d\.\d\.\d表示匹配一到多個數字&#xff0c;接著一個小數點&#xff0c;再接著一到多個數字&#xff0c;然后又一個小數點和一到多個數字&#xff0c;用來匹配類似 “2.1.1” 這樣的標題號部分。\s表示匹配一個空格。.*表示匹配…

力扣.旋轉矩陣Ⅱ

59. 螺旋矩陣 II - 力扣&#xff08;LeetCode&#xff09; 代碼區&#xff1a; class Solution {const int MAX25; public:vector<vector<int>> generateMatrix(int n) {vector<vector<int>> ans;vector<int> hang;int len_nn;int arry[25][25]…

軟件工程面試題(十)

1、OSI七層模型tcp四層模型是什么樣的 OSI七層參考模型 :物理層 、數據鏈路層 、網絡層 、傳輸層、應用層、會話層、表示層 TCP/IP:第一層網絡接口層第二層 第二層??網間層 第三層??傳輸層 第四層??應用層 2、JAVA測試模式(ZZ): 模式(一) Main 模式 模式(二)…

淘寶雙十一大促監控系統開發:實時追蹤爆品數據與流量波動

以下是開發一個淘寶雙十一大促監控系統&#xff0c;以實時追蹤爆品數據與流量波動的詳細步驟及示例代碼&#xff1a; 實現思路 數據獲取&#xff1a;利用淘寶 API 或者爬蟲技術&#xff0c;獲取商品的銷售數據、瀏覽量等信息。數據存儲&#xff1a;將獲取到的數據存儲到數據庫…

高并發金融系統,“可觀測-可追溯-可回滾“的閉環審計體系

一句話總結 在高并發金融系統中&#xff0c;審計方案設計需平衡"觀測粒度"與"系統損耗"&#xff0c;通過雙AOP實現非侵入式采集&#xff0c;三表機制保障操作原子性&#xff0c;最終形成"可觀測-可追溯-可回滾"的閉環體系。 業務痛點與需求 在…

Docker 的實質作用是什么

Docker 的實質作用是什么 目錄 Docker 的實質作用是什么**1. Docker 的實質作用****2. 為什么使用 Docker?****(1)解決環境一致性問題****(2)提升資源利用率****(3)簡化部署與擴展****(4)加速開發與協作****3. 舉例說明****總結**Docker 的實質是容器化平臺,核心作用…

【測試】每日3道面試題 3/29

每日更新&#xff0c;建議關注收藏點贊。 自動化測試中的PO模式 page object model POM 是一個設計模式&#xff0c;在自動化測試中將頁面元素和操作抽象為對象。具體是將每個頁面或頁面一部分封裝為一個類&#xff0c;包含頁面元素和相關操作。 PO 模式不僅適用于 Web 應用的自…

ISIS-4 LSP計算

上一章我們介紹了ISIS的LSDB的形成以及相關實驗 這一章我們來介紹ISIS是怎樣來計算我們的路由的 1、LSDB數據庫 之前我們在ISIS概述里面已經提及到Level-1的路由器設備只會維護Level-1的LSDB Level1-2會維護Level-1以及Level-2的LSDB,Level-2只會維護Level-2的LSDB 2、ATT置…

第7期:生成式AI倫理邊界——當技術撞上道德與法律的防火墻

現實版"黑鏡"事件 某直播平臺主播使用AI換臉技術冒充明星帶貨&#xff0c;當晚銷售額破億。三天后收到法院傳票——這不僅侵犯肖像權&#xff0c;生成的虛假宣傳內容還引發大規模消費投訴。這個案例讓行業意識到&#xff1a;沒有倫理約束的AI&#xff0c;就像沒有剎車…

Vue2 使用 v-if、v-else、v-else-if、v-show 以及 v-has 自定義指令實現條件渲染

提示&#xff1a;渲染就是顯示 文章目錄 前言v-if 的基礎用法v-elsev-else-ifv-show 和 v-if 對比自定義指令 v-hasv-if 和 v-has 結合使用場景完整示例補充說明 前言 提示&#xff1a;這里可以添加本文要記錄的大概內容&#xff1a; 在 Vue2 中&#xff0c;可以通過 v-if 和…