一、異常處理
1、異常概念引入
異常是一種 特殊的程序流控制機(jī)制 , 用于處理程序中可能出現(xiàn)的錯(cuò)誤或異常情況 ;
當(dāng)程序執(zhí)行錯(cuò)誤時(shí) , 由 throw 關(guān)鍵字拋出異常 , 并即跳轉(zhuǎn)到相應(yīng)的異常處理程序中 ; 如果沒(méi)有適當(dāng)?shù)漠惓L幚沓绦蛱幚碓摦惓?, 程序會(huì)崩潰終止 ;
異常與函數(shù)對(duì)比 :
- 函數(shù) 是一種 以 棧結(jié)構(gòu) 展開(kāi)的上下函數(shù)銜接的程序控制系統(tǒng) ;
- 異常 是一種 特殊的程序流控制機(jī)制 , 用于處理程序中可能出現(xiàn)的錯(cuò)誤或異常情況 ; 異常 依附于棧結(jié)構(gòu) , 卻可以同時(shí)設(shè)置多個(gè) 異常類型 作為 異常捕獲條件 ;
異常是跨函數(shù)的 , 下圖中 函數(shù) f 調(diào)用 函數(shù) g , 函數(shù) g 調(diào)用 函數(shù) h ;
在 函數(shù) h 中拋出異常 , 異常會(huì)沿著函數(shù) 調(diào)用順序 , 先拋給 函數(shù) g , 如果 g 不處理 , 則繼續(xù)向上拋給 函數(shù) f ;
上述 異常處理 機(jī)制 , 可以在不同的函數(shù)中 進(jìn)行 拋出異常 和 處理異常 的操作 ;
這樣 函數(shù)設(shè)計(jì)開(kāi)發(fā)時(shí) 只需要解決具體的問(wèn)題 , 不需要過(guò)多考慮 異常處理 ;
2、拋出異常語(yǔ)法
拋出異常 語(yǔ)法 : 使用 throw 關(guān)鍵字 , 拋出異常對(duì)象 ;
throw 異常對(duì)象;
代碼示例 : 在下面的函數(shù)中 , 拋出一個(gè) int 類型的異常 ;
// 1. 在 函數(shù) 中 拋出異常
void fun(int a) {
if (a == 0) {
// 拋出一個(gè) int 類型的異常
throw 2;
}
}
3、捕獲異常語(yǔ)法
異常捕獲 語(yǔ)法 : 在 try 代碼塊中執(zhí)行 可能拋出異常的 代碼 , 如果出現(xiàn)異常 , 就可以在 catch 分支中進(jìn)行捕獲 ;
try {
// 出現(xiàn)異常的代碼塊
} catch( 異常類型聲明 )
代碼示例 : 下面的代碼中 , 捕獲 try 代碼塊中產(chǎn)生的異常 ,
- 如果捕獲到 int 類型的異常 , 則執(zhí)行 catch (int e) 分支中的代碼 ,
- 如果捕獲到其它類型的異常 , 則執(zhí)行 catch ( … ) 分支中的代碼 ;
// 2. 捕獲并處理異常
try
{
// 調(diào)用可能產(chǎn)生異常的函數(shù)
fun(0);
}
catch (int e)
{
cout << "捕獲到異常 : " << e << endl;
}
catch ( ... )
{
// 捕獲 ... 可以捕獲未知其它類型的異常
cout << "捕獲到未知類型異常"<< endl;
}
4、異常捕獲流程
異常捕獲流程 :
- 拋出異常 : 如果遇到錯(cuò)誤 , 需要拋出異常 , 可以使用 throw 關(guān)鍵字 , 拋出一個(gè)異常對(duì)象 , 這個(gè)異常對(duì)象可以是任意類型 , 如 int 類型 ;
-
try 代碼塊處理異常 : 在 try 代碼塊中 , 執(zhí)行可能拋出異常的代碼 , 上方的代碼順序執(zhí)行到達(dá) try 代碼塊時(shí) , 則進(jìn)入 try 代碼塊 繼續(xù)執(zhí)行其中的代碼 ;
- 正常執(zhí)行 : 如果 try 保護(hù)段代碼正常執(zhí)行 , 沒(méi)有出現(xiàn)異常 , 則執(zhí)行完畢后繼續(xù)執(zhí)行 后續(xù)代碼 , 最后一個(gè) catch 分支之后的代碼 ;
-
出現(xiàn)異常 :
-
捕獲異常 : 如果出現(xiàn)了異常 , 恰好被 catch 分支捕獲 , 則執(zhí)行 catch 分支代碼 ;
- 處理異常 : 如果能處理該異常 , 則處理異常錯(cuò)誤 ;
- 繼續(xù)向上拋出異常 : 如果無(wú)法處理 , 則繼續(xù)向上拋出給調(diào)用者 , 讓上一級(jí)函數(shù)處理 ;
- 未捕獲異常 : 如果出現(xiàn)了異常 , 沒(méi)有被 catch 分支捕獲 , 則運(yùn)行 terminate 函數(shù) , 在該函數(shù)中調(diào)用 abort 終止程序 ;
-
捕獲異常 : 如果出現(xiàn)了異常 , 恰好被 catch 分支捕獲 , 則執(zhí)行 catch 分支代碼 ;
二、異常處理代碼示例
1、錯(cuò)誤代碼示例 - 拋出異常 / 不捕獲異常
錯(cuò)誤代碼示例 : 在下面的代碼中 , 沒(méi)有捕獲異常 , 則在執(zhí)行時(shí)會(huì)報(bào)錯(cuò) : " 0x755FF932 處(位于 HelloWorld.exe 中)有未經(jīng)處理的異常 " ;
#include "iostream"
using namespace std;
// 1. 在 函數(shù) 中 拋出異常
void fun(int a) {
if (a == 0) {
// 拋出一個(gè) int 類型的異常
throw 2;
}
}
int main() {
// 調(diào)用可能產(chǎn)生異常的函數(shù)
fun(0);
// 控制臺(tái)暫停 , 按任意鍵繼續(xù)向后執(zhí)行
system("pause");
return 0;
};
執(zhí)行結(jié)果 :
0x755FF932 處(位于 HelloWorld.exe 中)有未經(jīng)處理的異常:
Microsoft C++ 異常: int,位于內(nèi)存位置 0x00F6FB6C 處。
2、正確代碼示例 - 拋出異常 / 捕獲異常
異常捕獲完整代碼示例 :
#include "iostream"
using namespace std;
// 1. 在 函數(shù) 中 拋出異常
void fun(int a) {
if (a == 0) {
// 拋出一個(gè) int 類型的異常
throw 2;
}
}
int main() {
// 2. 捕獲并處理異常
try
{
// 調(diào)用可能產(chǎn)生異常的函數(shù)
fun(0);
}
catch (int e)
{
cout << "捕獲到異常 : " << e << endl;
}
catch ( ... )
{
// 捕獲 ... 可以捕獲未知其它類型的異常
cout << "捕獲到未知類型異常"<< endl;
}
// 控制臺(tái)暫停 , 按任意鍵繼續(xù)向后執(zhí)行
system("pause");
return 0;
};
執(zhí)行結(jié)果 :
捕獲到異常 : 2
請(qǐng)按任意鍵繼續(xù). . .
3、正確代碼示例 - 拋出異常 / 捕獲異常不處理繼續(xù)拋出異常
異常是跨函數(shù)的 , 異常會(huì)從本函數(shù)中拋給調(diào)用本函數(shù)的調(diào)用者 ( 調(diào)用函數(shù) ) ;
- 如 : 在 main 函數(shù)中調(diào)用 fun 函數(shù) , 如果 fun 函數(shù)中拋出異常 , 則拋給了 main 函數(shù) , 需要在 main 函數(shù)中捕獲并處理異常 ;
在下面的示例中 , fun2 函數(shù)中捕獲 fun 函數(shù)中的 異常未處理 , 拋到了 main 函數(shù)中 ;
main 函數(shù)中的異常必須處理 , 否則程序崩潰 ;
代碼示例 :
#include "iostream"
using namespace std;
// 1. 在 函數(shù) 中 拋出異常
void fun(int a) {
if (a == 0) {
// 拋出一個(gè) int 類型的異常
throw 2;
}
}
// 3. 捕獲異常不處理 , 繼續(xù)向上拋出
void fun2(int a) {
try
{
// 執(zhí)行可能拋出異常的函數(shù)
fun(a);
}
catch (int e)
{
// 捕獲到了異常, 但是不處理繼續(xù)向上拋出
throw;
}
}
int main() {
// 2. 捕獲并處理異常
try
{
// 調(diào)用可能產(chǎn)生異常的函數(shù)
//fun(0);
// 異常是跨函數(shù)的
// 調(diào)用可能產(chǎn)生異常的函數(shù)
// 該 fun2 函數(shù)中捕獲 fun 函數(shù)中的 異常未處理
// 拋到了 main 函數(shù)中
fun2(0);
}
catch (int e)
{
cout << "捕獲到異常 : " << e << endl;
}
catch ( ... )
{
// 捕獲 ... 可以捕獲未知其它類型的異常
cout << "捕獲到未知類型異常"<< endl;
}
// 控制臺(tái)暫停 , 按任意鍵繼續(xù)向后執(zhí)行
system("pause");
return 0;
};
執(zhí)行結(jié)果 :文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-757123.html
捕獲到異常 : 2
請(qǐng)按任意鍵繼續(xù). . .
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-757123.html
到了這里,關(guān)于【C++】異常處理 ① ( 異常概念引入 | 拋出異常語(yǔ)法 | 捕獲異常語(yǔ)法 | 異常捕獲流程 | 異常處理代碼示例 )的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!