網站首頁 編程語言 正文
基本的異常處理
異常處理機制:暫緩問題處理,不在當前函數中處理,在他的調用者中處理(先上車,后補票)
什么是異常:任何東西都可以認為是異常,錯誤只是異常的一種
異常一旦被拋出,不做處理,如果引發異常,會調用默認abort函數終止程序
捕獲和處理異常:
throw 拋出異常: (值是任何類型都可以,只是我們處理異常的一個參照,類似返回值)
try(檢查,捕獲)和catch(處理異常): 必須是一起出現,并且它們的括號{ }不能省略
tip:? ?任何東西都可以認為是異常,錯誤只是異常中的一種---出現一種情況不能讓程序正常運行
怎么拋出異常
//求a和b的余數 怎么拋出異常 int division(int a,int b){ if(b==0) throw 0; //拋出一個值(任意)--->之后處理 return a/b; } void print(int a,int b){ cout<<division(a,b); } int main(){ print(1,0); } /* 把b==0 的情況稱為異常,b==0 時代碼不成立,會調用默認abort函數終止程序 */
異常一旦被拋出,不做處理,如果引發異常,會調用默認abort函數終止程序?
捕獲和處理異常
//try 與catch必須是一起出現,并且他們的括號{}不能省略 try { //正常需要檢查是否存在異常的代碼 } catch(類型) //理解為switch中case語句 { //處理是根據拋出數據類型決定如何處理 匹配項 匹配拋出異常的類型 } //一個try可以對應多個catch try { //... } catch(int) { } catch(double) { } catch(string) { } //catch和if else_if 執行機制是一樣的,只能執行一個匹配項
小知識:
- 對try{ }? ?catch(){ } 的理解:在當前位置引發異常,直接從這個位置跳到catch的位置執行catch的代碼 --- 類似switch case 語句
- catch中int和char不會做轉換
- 寫兩個相同的類型不被允許,哪段代碼先引發異常就先調用catch
int division(int a,int b){ if(b==0) throw 0; return a/b; } void print(int a,int b){ cout<<division(a,b); } int main(){ try { print(1,0); //檢查異常 cout<<"別的代碼"<<endl; //這一句不會運行,會直接跳到catch } catch(int) //拋出的是int類型,捕獲int類型 { cout<<"除數不能為0"<<endl; } }
程序能拋出(存在)多個異常,但是只能同時處理1個異常,不能同時引發多個異常
不存在異常的描述 --- 標識性作用? ??
- throw ()
- noexcept
//某個函數不存在異常,在某個函數后面用throw() 描述,表示它不存在異常 void print() throw() { cout << "當前函數不存在拋出異常操作" << endl; } void printData() noexcept { cout << "c++新標準中的關鍵字: 不存在拋出異常操作" << endl; //throw 0; 一旦說明沒有異常操作,就不能拋出 }
刪減符 ...
任何類型的異常都捕獲? ? 不管拋出啥,在哪里拋出的,只要引發異常都可以捕獲到
catch(...) { cout <<"捕獲任何類型的異常"<< endl; }
異常處理中的傳參操作? --- 可以寫一個變量進去
catch(int a)/* 隱藏了一個傳參操作 可以傳任何類型,包括自定義類型都可以 */
注意c++中string的處理? ? /* string類型與const char* 類型區別 */
代碼解析:
對? 通過拋出字符串,隱藏了一個傳參操作? 的理解
int divisor(int a, int b) { if (b == 0) throw string("除數不能為0"); return a / b; } int main() { try { divisor(1, 0); } catch (string str) //把throw的內容賦值給str str="除數不能為0" { cout << str << endl; } }
注意string類型與const char* 類型區別? --- 出現類型不匹配,c++對傳參類型要求更嚴格
int divisor(int a, int b) { if (b == 0) throw "除數不能為0"; //拋出異常 解析為char* 類型 寫catch時不能直接當作string if(b==1) throw "除數不能為1"; /* 不同問題的拋出,不能用固定類型(int、char...), 可以選擇 拋出不同字符串處理 string1,string2,string3... 通過傳 參的方式去描述問題 */ if(b==2) throw string("除數不能為2"); //需構造無名參數作捕獲對象處理--->需要自己觸發 return a / b; } int main() { try { divisor(1, 0); //直接觸發異常 } catch (const char* str) //拋出的是char* 類型,不能當作string { cout << str << endl; } try { divisor(1, 2); } catch (string str) //如果要捕獲string類型,需要自己構造一個string對象返回 { cout << str << endl; //直接輸出str } }
可以拋出自己類的對象
class Error { public: Error(const char* str = "未知錯誤") :str(str) {} const char* what()const { return str.c_str(); } protected: string str; }; void insertArray(int array[], int* curNum, int posData,int maxLength) { if (*curNum >= maxLength) //3>=3 { throw Error("數組下標溢出!"); } //0 1 2 array[*curNum] = posData; //array[3]=3 (*curNum)++; } int main(){ try { int array[3] = { 0,0,0 }; int curNum = 0; for (int i = 0; i < 4; i++) { insertArray(array, &curNum, i, 3); } } catch (Error str) { cout << str.what() << endl; } return 0; }
標準庫當中的異常類
#include<exception> //父類(基類)
子類很多,子類描述的問題不同而已
例子: const char* _ptr; 一個數據成員,用于描述標準庫當中異常的字符串,用字符指針存放那個字符串
what( )方法? 用于返回數據成員的? ? ? ? 1.虛函數? ? ? ? 2.不存在異常
return _ptr ? _ptr : "unknow";判斷char* 類型的指針是不是為空,不等于空,返回你描述的錯誤,等于空(由于沒有傳參),返回未知錯誤"unknow"
引發標準庫中內存申請失敗的異常
發現代碼出現abort( )錯誤,可以通過這種方式找到,這里是針對內存申請失敗做了單一處理,如果不做處理,會直接調用abort函數終止程序
#include <exception> #include <iostream> using namespace std; class Exception { public: Exception(const char* ptr="UNKNOW") :ptr(const_cast<char*>(ptr)){} /*構造函數 干掉 常屬性*/ virtual const char* what() const //父類是虛函數 且不存在異常 { return ptr; } protected: char* ptr; }; //子類繼承父類 class Bad_alloc :public Exception { public: Bad_alloc(const char* _Message = "bad exception") :Exception(_Message) {} /*調用父類 的構造函數拋出bad exception*/ protected: }; //子類繼承父類 調用父類構造函數 class Run_time :public Exception { public: Run_time(const char* _Message = "run_time error") :Exception(_Message) {} protected: }; int main() { try { while (1) { int* p = new int[1024*1024*10];//一直做內存申請,不做釋放,最后一定會內存申請失敗 } } catch (bad_alloc& object) /* 內存申請失敗,調用bad_alloc 標準庫中的異常,創建一個對象接收一 下,子類中的what()方法調用父類中的what()方法打印 */ { cout << object.what() << endl; } return 0; } /*輸出*/ bad allocation //調用時拋出 bad allocation 是子類對象調用繼承下來的what()方法 //一般寫代碼出現莫名的中斷,原因是不做異常處理,引發了abort函數中斷程序,一般這種錯誤都是特殊錯誤
標準庫中傳兩個參數起到標識作用,由于:引發了不同的錯誤,不同錯誤對應了不同的錯誤編碼 對這些錯誤有特定的描述 ---> 工具 ---> 錯誤查找 ---> 輸入錯誤編碼
值:3
錯誤信息:系統找不到指定的路徑?
原文鏈接:https://blog.csdn.net/weixin_60569662/article/details/121862864
相關推薦
- 2022-06-22 關于Metalama使用Fabric操作項目或命名空間的問題_實用技巧
- 2022-11-26 React從插槽、路由、redux的詳細過程_React
- 2022-10-22 Python?NumPy教程之數組的創建詳解_python
- 2022-10-04 淺析C++模板類型中的原樣轉發和可變參數的實現_C 語言
- 2021-11-02 利用shadowsocks搭建局域網透明網關_Linux
- 2022-05-13 e engine “node“ is incompatible with this module.
- 2022-07-18 C++函數模板和類模板詳解
- 2022-12-13 Flutter?阻止系統鍵盤彈出的優雅方式_Android
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支