個詞,今天就來做詳細的介紹,文中通過代碼示例給大家介紹的非常詳細,具有一定參考價值,需要的朋友可以參考下" />

最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++異常處理的方式總結

 更新時間:2023年12月19日 09:39:14   作者:杭電碼農(nóng)-NEO  
C++有一套獨立的異常處理機制,相信大家一定聽說過try,catch這兩
個詞,今天就來做詳細的介紹,文中通過代碼示例給大家介紹的非常詳細,具有一定參考價值,需要的朋友可以參考下

1. 前言

C++有一套獨立的異常處理機制,相信大家一定聽說過try,catch這兩個詞,今天就來做詳細的介紹

本篇文章著重講解C++異常處理的方式,三個關鍵字,tyr,catch,throw,并且介紹異常的用法和自定義體系的異常以及智能指針在異常處理中的使用場景.其中,會復習C語言異常處理的方式

2. C語言處理異常的方式

最經(jīng)典的處理方式:使用assert

assert的缺陷:

如果在代碼中使用assert,則只在debug模式下有效,在release模式下會失效.并且只要有錯誤就會直接終止程序,這明顯不符合實際,比如說在使用微信時,由于網(wǎng)絡問題信息沒發(fā)出去,這時直接將微信程序終止了,這樣做會被亂棍打死!

C語言還能用錯誤碼返回異常信息

錯誤碼errno的缺陷:

返回的錯誤碼是一個數(shù)字,程序員還需去查表來得知這個錯誤碼是什么意思,并且就算查找了錯誤碼的信息,可能它說的不清楚,也不好看錯誤信息

綜上所述,C語言處理異常的方式還是不夠完美,于是祖師爺寫了一套自己的

3. C++異常概念

當一個函數(shù)發(fā)現(xiàn)自己無法處理的錯誤時就可以拋出異常,讓函數(shù)的直接或間接的調(diào)用者處理這個錯誤。

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

使用方法:

try{
	int a,b;
	cin>>a>>b;
	if(b == 0)
		throw "除0錯誤"
	cout<<(a/b)<<endl;
}

catch(string str)
{
	//......
}

如果有一個塊拋出一個異常,捕獲異常的方法會使用 try 和 catch 關鍵字。try 塊中放置可能拋出異常的代碼,try 塊中的代碼被稱為保護代碼,一旦throw后,會直接跳到catch的位置,后面的代碼不會執(zhí)行

4. 異常的拋出和匹配原則

異常的拋出和匹配有以下機制:

拋出的內(nèi)容和捕捉的內(nèi)容要一致

如果你在throw時拋出一個字符串,但是在catch捕獲異常時的參數(shù)卻寫的是整數(shù)那么這個拋出的異常就不會去這個catch

void a(){throw "測試中";}
void b(){a()}
void c(){b()}
int main()
{
	try{
		c();
	}
	catch(string str)
	{}

try可以嵌套多層

try和catch不僅僅可以在一個作用域使用,還可以在最外層try,然后嵌套多層函數(shù),在最里面的函數(shù)throw!

void a(){throw "測試中";}
void b(){a()}
void c(){b()}
int main()
{
	try{
		c();
	}
	catch(string str)
	{}

throw和catch遵循就近原則

若寫了多個catch,并且這些catch都和throw的內(nèi)容匹配,則會跳轉到與throw最近的內(nèi)個catch中!

double Division(int a, int b)
{
    // 當b == 0時拋出異常
	if (b == 0)
	  throw "除0錯誤!";
   else
   	  return ((double)a / (double)b);
}
void Func()
{
	int len, time;
	cin >> len >> time;
	cout << Division(len, time) << endl;
	catch (const char* errmsg) {//這個catch與throw相距最近,會優(yōu)先到這兒
	cout << errmsg << "111" << endl;
	}
}
int main()
{
	try {
		Func();
	}
	catch (const char* errmsg) {
		cout << errmsg << "222" << endl;
	}
	return 0;
}

catch(...)可以捕獲任意類型的異常

在公司寫大工程的時候,會和很多同事合作寫代碼,大家都會拋出異常,但是你不能確定是不是所有人拋出的類型你都有相應的catch可以接收,若拋出一個異常沒有被捕獲會直接報錯,所以…的作用很明顯,用來兜底!一般用于接收一些未知異常

double Division(int a, int b)
{
    // 當b == 0時拋出異常
	if (b == 0)
	  throw "除0錯誤!";
   else
   	  return ((double)a / (double)b);
}
void Func()
{
	int len, time;
	cin >> len >> time;
	cout << Division(len, time) << endl;
	catch (const char* errmsg) {//這個catch與throw相距最近,會優(yōu)先到這兒
	cout << errmsg << "111" << endl;
	}
}
int main()
{
	try {
		Func();
	}
	catch (const char* errmsg) {
		cout << errmsg << "222" << endl;
	}
	 catch(...){
   cout<<"未知異常"<<endl;           
    }
	return 0;
}

基類可以接受拋出的子類對象

拋出和捕獲有一個例外,那就是可以拋出子類對象,用基類捕獲,這個在實際場景中非常實用,我們會在后面詳談

5. 異常的重新拋出

有可能在捕獲異常時,一次捕獲不能完全解決問題,比如我們想在main函數(shù)中處理所有的異常,在非main函數(shù)中打印一下異常信息然后再將異常拋到main中統(tǒng)一做處理

double Division(int a, int b)
{
	// 當b == 0時拋出異常
	if (b == 0)
	{
		throw "Division by zero condition!";
	}
	return (double)a / (double)b;
}
void Func()
{
	// 這里可以看到如果發(fā)生除0錯誤拋出異常,另外下面的array沒有得到釋放。
	// 所以這里捕獲異常后并不處理異常,異常還是交給外面處理,這里捕獲了再
	// 重新拋出去。
	int* array = new int[10];
	try {
		int len, time;
		cin >> len >> time;
		cout << Division(len, time) << endl;
	}
	catch (...)
	{
		cout << "delete []" << array << endl;
		delete[] array;
		throw;
	}
	
	cout << "delete []" << array << endl;
	delete[] array;
}
int main()
{
	try
	{
		Func();
	}
	catch (const char* errmsg)
	{
		cout << errmsg << endl;
	}
	return 0;
}

在上面的場景中,如果拋出異常,就會直接走到catch處,不會調(diào)用delete釋放釋放在堆上開辟的空間,就會有問題,所以第一次catch時先處理釋放空間的問題然后將異常再次拋出后再處理異常問題

6. RAII思想在異常體系中的使用

在異常體系中在堆上申請空間,或者打開某個問題時常容易出問題,因為堆上開辟的空間要顯示調(diào)用delete處理而打開的文件也要顯示調(diào)用fclose關閉所以一旦發(fā)生異常就會直接跳轉到catch的位置,有可能直接忽略了釋放函數(shù)這也就是導致了資源并沒有被釋放!

在異常體系中最好使用RAII思想申請資源

即使拋出異常后直接跳到catch也沒問題

當出了對象作用域會自動調(diào)用析構釋放!

double Division(int a, int b)
{
	// 當b == 0時拋出異常
	if (b == 0)
	{
		throw "Division by zero condition!";
	}
	return (double)a / (double)b;
}
void Func()
{
	shared_ptr<int> array(new int(10));
	try {
		int len, time;
		cin >> len >> time;
		cout << Division(len, time) << endl;
	}
}
int main()
{
	try
	{
		Func();
	}
	catch (const char* errmsg)
	{
		cout << errmsg << endl;
	}
	return 0;
}

7. 自定義異常體系

實際使用中很多公司都會自定義自己的異常體系進行規(guī)范的異常管理,因為一個項目中如果大家隨意拋異常,那么外層的調(diào)用者基本就沒辦法玩了,所以實際中都會定義一套繼承的規(guī)范體系。這樣大家拋出的都是繼承的派生類對象,捕獲一個基類就可以了

在這里插入圖片描述

不同的部分可以拋出不同的異常,然后在總的main函數(shù)中使用基類捕獲所有的異常再來進行特殊的處理

8. C++標準庫的異常體系

這里的內(nèi)容屬于了解范疇,用幾張圖帶大家了解一下:

在這里插入圖片描述

在這里插入圖片描述

實際中都是我們自己去實現(xiàn)一個異常體系
因為C++庫做的并不好

9. 總結以及拓展

異??傮w而言,利大于弊,所以工程中我們還是鼓勵使用異常的。另外OO的語言基本都是用異常處理錯誤,這也可以看出這是大勢所趨。

除此之外,異常還有一套規(guī)范,因為比較雞肋,所以放在了最后來介紹:

  • 異常規(guī)格說明的目的是為了讓函數(shù)使用者知道該函數(shù)可能拋出的異常有哪些。 可以在函數(shù)的后面接throw(類型),列出這個函數(shù)可能拋擲的所有異常類型。
  • 函數(shù)的后面接throw(),表示函數(shù)不拋異常。
  • 若無異常接口聲明,則此函數(shù)可以拋擲任何類型的異常。
// 這里表示這個函數(shù)會拋出A/B/C/D中的某種類型的異常
void fun() throw(A,B,C,D);
// 這里表示這個函數(shù)只會拋出bad_alloc的異常
void* operator new (std::size_t size) throw (std::bad_alloc);
// 這里表示這個函數(shù)不會拋出異常
void* operator delete (std::size_t size, void* ptr) throw();
// C++11 中新增的noexcept,表示不會拋異常
thread() noexcept;
thread (thread&& x) noexcept;

之所以比較雞肋是因為就算你寫了noexcept,再拋出異常,在某些編譯器也不會報錯

以上就是C++異常處理的方式總結的詳細內(nèi)容,更多關于C++異常處理方式的資料請關注腳本之家其它相關文章!

相關文章

  • VC實現(xiàn)批量刪除指定文件的方法

    VC實現(xiàn)批量刪除指定文件的方法

    這篇文章主要介紹了VC實現(xiàn)批量刪除指定文件的方法,是一個比較普遍且實用的功能,需要的朋友可以參考下
    2014-07-07
  • C++實現(xiàn)圖書館管理系統(tǒng)

    C++實現(xiàn)圖書館管理系統(tǒng)

    這篇文章主要為大家詳細介紹了C++實現(xiàn)圖書館管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • C語言實現(xiàn)食堂就餐管理系統(tǒng)(帶鏈表)

    C語言實現(xiàn)食堂就餐管理系統(tǒng)(帶鏈表)

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)食堂就餐管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • C++實現(xiàn)關機功能詳細代碼

    C++實現(xiàn)關機功能詳細代碼

    大家好,本篇文章主要講的是C++實現(xiàn)關機功能詳細代碼,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • c++?qt自定義搜索編輯框的實現(xiàn)方法

    c++?qt自定義搜索編輯框的實現(xiàn)方法

    這篇文章主要介紹了c++?qt自定義搜索編輯框,通過自定義QLineEdit,在編輯框里添加布局,將按鈕設置在右邊,當點擊按鈕搜索按鈕時發(fā)送信號到主界面做相應的操作,需要的朋友可以參考下
    2022-03-03
  • C++實現(xiàn)LeetCode(87.攪亂字符串)

    C++實現(xiàn)LeetCode(87.攪亂字符串)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(87.攪亂字符串),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C/C++中線程基本概念與創(chuàng)建詳解

    C/C++中線程基本概念與創(chuàng)建詳解

    線程是在進程中產(chǎn)生的一個執(zhí)行單元,是CPU調(diào)度和分配的最小單元,其在同一個進程中與其他線程并行運行,他們可以共享進程內(nèi)的資源。本文就和大家一起聊聊線程基本概念以及如何創(chuàng)建多線程,需要的可以參考一下
    2022-09-09
  • Qt QML使用虛擬鍵盤的示例代碼

    Qt QML使用虛擬鍵盤的示例代碼

    這篇文章主要為大家詳細介紹了Qt QML使用虛擬鍵盤的相關知識,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2024-01-01
  • C++ vector刪除符合條件的元素示例分享

    C++ vector刪除符合條件的元素示例分享

    這篇文章主要介紹了C++ vector刪除符合條件的元素示例,需要的朋友可以參考下
    2014-02-02
  • C++中靜態(tài)初始化數(shù)組與動態(tài)初始化數(shù)組詳解

    C++中靜態(tài)初始化數(shù)組與動態(tài)初始化數(shù)組詳解

    今天小編就為大家分享一篇C++中靜態(tài)初始化數(shù)組與動態(tài)初始化數(shù)組詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07

最新評論

东阿县| 大邑县| 贵阳市| 信宜市| 措美县| 平山县| 同心县| 海晏县| 辛集市| 蒲城县| 额敏县| 彰化市| 中超| 安康市| 荥阳市| 潢川县| 汉寿县| 资兴市| 成武县| 喀喇| 巴东县| 莱芜市| 闸北区| 蒲江县| 深州市| 扶风县| 全州县| 宁津县| 彭山县| 策勒县| 汶上县| 左云县| 旌德县| 陆丰市| 通河县| 昭通市| 朝阳区| 淮安市| 牟定县| 贡嘎县| 加查县|