溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎么深入了解C++異常處理

發(fā)布時(shí)間:2021-12-15 13:14:36 來源:億速云 閱讀:428 作者:柒染 欄目:開發(fā)技術(shù)

本篇文章為大家展示了怎么深入了解C++異常處理,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。

基本的異常處理

異常處理機(jī)制:暫緩問題處理,不在當(dāng)前函數(shù)中處理,在他的調(diào)用者中處理(先上車,后補(bǔ)票)

什么是異常:任何東西都可以認(rèn)為是異常,錯(cuò)誤只是異常的一種

異常一旦被拋出,不做處理,如果引發(fā)異常,會(huì)調(diào)用默認(rèn)abort函數(shù)終止程序

捕獲和處理異常:

throw 拋出異常: (值是任何類型都可以,只是我們處理異常的一個(gè)參照,類似返回值)

try(檢查,捕獲)和catch(處理異常): 必須是一起出現(xiàn),并且它們的括號(hào){ }不能省略

tip:   任何東西都可以認(rèn)為是異常,錯(cuò)誤只是異常中的一種---出現(xiàn)一種情況不能讓程序正常運(yùn)行

怎么深入了解C++異常處理

怎么拋出異常

//求a和b的余數(shù)    怎么拋出異常
int division(int a,int b){
    if(b==0)
        throw 0;    //拋出一個(gè)值(任意)--->之后處理
    return a/b;
}
void print(int a,int b){
 
    cout<<division(a,b);
}
int main(){
 
    print(1,0);
 
}
/* 把b==0 的情況稱為異常,b==0 時(shí)代碼不成立,會(huì)調(diào)用默認(rèn)abort函數(shù)終止程序 */

異常一旦被拋出,不做處理,如果引發(fā)異常,會(huì)調(diào)用默認(rèn)abort函數(shù)終止程序 

怎么深入了解C++異常處理

捕獲和處理異常

//try 與catch必須是一起出現(xiàn),并且他們的括號(hào){}不能省略
try
{
	//正常需要檢查是否存在異常的代碼 
}
catch(類型)     //理解為switch中case語句
{
    //處理是根據(jù)拋出數(shù)據(jù)類型決定如何處理 匹配項(xiàng) 匹配拋出異常的類型
}
 
//一個(gè)try可以對(duì)應(yīng)多個(gè)catch
try
{
	//...    
}
catch(int)
{
	    
}
catch(double)
{
    
}
catch(string)
{
	    
}
//catch和if else_if 執(zhí)行機(jī)制是一樣的,只能執(zhí)行一個(gè)匹配項(xiàng)

小知識(shí):

  • 對(duì)try{ }   catch(){ } 的理解:在當(dāng)前位置引發(fā)異常,直接從這個(gè)位置跳到catch的位置執(zhí)行catch的代碼 --- 類似switch case 語句

  • catch中int和char不會(huì)做轉(zhuǎn)換

  • 寫兩個(gè)相同的類型不被允許,哪段代碼先引發(fā)異常就先調(diào)用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;    //這一句不會(huì)運(yùn)行,會(huì)直接跳到catch
    }    
    catch(int)                    //拋出的是int類型,捕獲int類型
    {
        cout<<"除數(shù)不能為0"<<endl;
    }
}

程序能拋出(存在)多個(gè)異常,但是只能同時(shí)處理1個(gè)異常,不能同時(shí)引發(fā)多個(gè)異常

不存在異常的描述 --- 標(biāo)識(shí)性作用    

  • throw ()

  • noexcept

//某個(gè)函數(shù)不存在異常,在某個(gè)函數(shù)后面用throw() 描述,表示它不存在異常
void  print() throw() 
{
	cout << "當(dāng)前函數(shù)不存在拋出異常操作" << endl;
}
void printData() noexcept 
{
	cout << "c++新標(biāo)準(zhǔn)中的關(guān)鍵字: 不存在拋出異常操作" << endl;
	//throw 0;  一旦說明沒有異常操作,就不能拋出
}

刪減符 ...

任何類型的異常都捕獲    不管拋出啥,在哪里拋出的,只要引發(fā)異常都可以捕獲到

catch(...)
{
 
    cout <<"捕獲任何類型的異常"<< endl;
}

異常處理中的傳參操作  --- 可以寫一個(gè)變量進(jìn)去

catch(int a)/* 隱藏了一個(gè)傳參操作 可以傳任何類型,包括自定義類型都可以 */

注意c++中string的處理    /* string類型與const char* 類型區(qū)別 */

代碼解析:

對(duì)  通過拋出字符串,隱藏了一個(gè)傳參操作  的理解

int divisor(int a, int b) 
{
	if (b == 0)
		throw string("除數(shù)不能為0");    
	return a / b;
}
 
int main()
{
	try
	{
		divisor(1, 0);   
	}
	catch (string str)    //把throw的內(nèi)容賦值給str    str="除數(shù)不能為0"
	{
		cout << str << endl;
	}
}

注意string類型與const char* 類型區(qū)別  --- 出現(xiàn)類型不匹配,c++對(duì)傳參類型要求更嚴(yán)格

int divisor(int a, int b) 
{
	if (b == 0)
		throw "除數(shù)不能為0";    //拋出異常  解析為char* 類型 寫catch時(shí)不能直接當(dāng)作string
	if(b==1)
		throw "除數(shù)不能為1";    /* 不同問題的拋出,不能用固定類型(int、char...), 可以選擇
                                  拋出不同字符串處理 string1,string2,string3... 通過傳
                                  參的方式去描述問題 */
	if(b==2)
		throw string("除數(shù)不能為2");  //需構(gòu)造無名參數(shù)作捕獲對(duì)象處理--->需要自己觸發(fā)
	return a / b;
}
 
int main()
{
	try
	{
		divisor(1, 0);       //直接觸發(fā)異常
	}
	catch (const char* str)  //拋出的是char* 類型,不能當(dāng)作string
	{
		cout << str << endl;
	}
	try
	{
		divisor(1, 2);
	}
	catch (string str)    //如果要捕獲string類型,需要自己構(gòu)造一個(gè)string對(duì)象返回
	{
		cout << str << endl;    //直接輸出str
	}
}

可以拋出自己類的對(duì)象

class Error 
{
public:
	Error(const char* str = "未知錯(cuò)誤") :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("數(shù)組下標(biāo)溢出!");
	}
	//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;
}

標(biāo)準(zhǔn)庫當(dāng)中的異常類

 #include<exception>    //父類(基類)

子類很多,子類描述的問題不同而已

例子: const char* _ptr; 一個(gè)數(shù)據(jù)成員,用于描述標(biāo)準(zhǔn)庫當(dāng)中異常的字符串,用字符指針存放那個(gè)字符串

what( )方法  用于返回?cái)?shù)據(jù)成員的        1.虛函數(shù)        2.不存在異常

return _ptr ? _ptr : "unknow";判斷char* 類型的指針是不是為空,不等于空,返回你描述的錯(cuò)誤,等于空(由于沒有傳參),返回未知錯(cuò)誤"unknow"

怎么深入了解C++異常處理

怎么深入了解C++異常處理

怎么深入了解C++異常處理

怎么深入了解C++異常處理

怎么深入了解C++異常處理

引發(fā)標(biāo)準(zhǔn)庫中內(nèi)存申請(qǐng)失敗的異常

發(fā)現(xiàn)代碼出現(xiàn)abort( )錯(cuò)誤,可以通過這種方式找到,這里是針對(duì)內(nèi)存申請(qǐng)失敗做了單一處理,如果不做處理,會(huì)直接調(diào)用abort函數(shù)終止程序

#include <exception>
#include <iostream>
using namespace std;
class Exception 
{
public:
	Exception(const char* ptr="UNKNOW") :ptr(const_cast<char*>(ptr)){} /*構(gòu)造函數(shù) 干掉            
                                                                         常屬性*/
	virtual const char* what() const    //父類是虛函數(shù) 且不存在異常
	{
		return ptr;
	}
protected:
	char* ptr;
};
//子類繼承父類    
class Bad_alloc :public Exception
{
public:
	Bad_alloc(const char* _Message = "bad exception") :Exception(_Message) {} /*調(diào)用父類 
                                                           的構(gòu)造函數(shù)拋出bad exception*/
protected:
};
//子類繼承父類    調(diào)用父類構(gòu)造函數(shù)
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];//一直做內(nèi)存申請(qǐng),不做釋放,最后一定會(huì)內(nèi)存申請(qǐng)失敗
		}
	}
	catch (bad_alloc& object) /* 內(nèi)存申請(qǐng)失敗,調(diào)用bad_alloc 標(biāo)準(zhǔn)庫中的異常,創(chuàng)建一個(gè)對(duì)象接收一            
                                 下,子類中的what()方法調(diào)用父類中的what()方法打印 */
    {
 
		cout << object.what() << endl;
	}
	return 0;
}
/*輸出*/
 
bad allocation    //調(diào)用時(shí)拋出 bad allocation 是子類對(duì)象調(diào)用繼承下來的what()方法
 
//一般寫代碼出現(xiàn)莫名的中斷,原因是不做異常處理,引發(fā)了abort函數(shù)中斷程序,一般這種錯(cuò)誤都是特殊錯(cuò)誤

標(biāo)準(zhǔn)庫中傳兩個(gè)參數(shù)起到標(biāo)識(shí)作用,由于:引發(fā)了不同的錯(cuò)誤,不同錯(cuò)誤對(duì)應(yīng)了不同的錯(cuò)誤編碼 對(duì)這些錯(cuò)誤有特定的描述 ---> 工具 ---> 錯(cuò)誤查找 ---> 輸入錯(cuò)誤編碼

怎么深入了解C++異常處理

值:3

錯(cuò)誤信息:系統(tǒng)找不到指定的路徑 

上述內(nèi)容就是怎么深入了解C++異常處理,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

c++
AI