欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++ 中的異常拋出和捕獲方式

 更新時間:2022年07月25日 09:33:49   作者:止步聽風  
這篇文章主要介紹了C++ 中的異常拋出和捕獲方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

在 C 語言中,如果發(fā)生錯誤,上級函數(shù)要進行出錯處理,層層上傳,容易造成過多的出錯處理代碼,并且傳遞的效率比較低下。

C++ 中的異常

C++ 中,異常的引發(fā)和異常的處理不必處于同一個函數(shù)中,因此底層函數(shù)可以著重于解決具體問題,而不必過多的考慮異常處理

異常是專門針對抽象編程中的一系列錯誤處理的,遇到錯誤信息就轉(zhuǎn)到若干級之上進行重新嘗試

異常脫離于函數(shù)機制,決定了其對函數(shù)的跨越式回跳

語法

try
{
? ? statement;
}
catch(ExceptionType var)
{
? ? statement;
}

被檢測的語句放在 try 塊中

try catch 語句中的花括號是語法的一部分,不能省略

try-catch 結(jié)構(gòu)中,只能有一個 try 塊,catch 塊可以有多個,以便與不同的類型信息匹配,有點類似于 switch-case 結(jié)構(gòu)

利用 throw 拋出的異常類型,可以傳遞系統(tǒng)預(yù)定義的標準類型或自定義類型

從 throw 拋出異常,到 catch 捕獲異常,有點類似與利用函數(shù)的返回值進行復(fù)制一樣,因此如果使用了自定義類型,需要考慮自定義類型的賦值和拷貝問題

如果 catch 語句沒有與之相匹配的異常類型信息,可以用(...)表示可以捕獲任何異常類型的信息,有點類似與 switch-case 結(jié)構(gòu)中的 default

try-catch 結(jié)構(gòu)可以與 throw 在同一函數(shù)中,也可以不在同一個函數(shù)中,throw 拋出異常后,會先在本函數(shù)中尋找與之相匹配的 catch 塊,如果沒有與之相匹配的 catch,就可以轉(zhuǎn)到上一層 try-catch,如果仍然沒有

匹配到,則轉(zhuǎn)到再上一層 try-catch...,如果最終到不到與之匹配的 try-catch 塊,系統(tǒng)就會調(diào)用系統(tǒng)函數(shù),terminal 使程序終止

#include <iostream>
?
using namespace std;
?
void func1()
{
? ? double a;
? ? try{
? ? ? ? throw a;
? ? }catch(double)
? ? {
? ? ? ? cout<<"catch func1()"<<endl; //throw
? ? }
? ? cout<<"end func1()"<<endl;
? ? return ;
}
?
void func2()
{
? ? try{
? ? ? ? func1();
? ? }catch(int)
? ? {
? ? ? ? cout<<"catch func2()"<<endl;
? ? }
? ? cout<<"end func2()"<<endl;
}
?
void func3()
{
? ? try{
? ? ? ? func2();
? ? }catch(char)
? ? {
? ? ? ? cout<<"catch func3()"<<endl;
? ? }
? ? cout<<"end func3()"<<endl;
}
?
int main()
{
? ? try{
? ? ? ? func3();
? ? }catch(double)
? ? {
? ? ? ? cout<<"catch main"<<endl;
? ? }
? ? cout<<"end main"<<endl;
? ? return 0;
}

結(jié)果為:

catch func1()
end func1()
end func2()
end func3()
end main

上邊的異常傳遞路線為 func3->func2()->func1(),在 func1 中找到對應(yīng)的 catch 塊,然后執(zhí)行對應(yīng) catch 塊中的語句,輸出:

catch func1()

整個的異常處理已經(jīng)結(jié)束,跳出 func1() 的 try-catch 塊,繼續(xù)執(zhí)行 func1() 的函數(shù)體,陸續(xù)輸出:

end func1()
end func2()
end func3()
end main

此時進程結(jié)束。

如果將 func1() 中的 catch 到的異常類型換個類型,如:

catch(void *)

結(jié)果為:

catch main
end main

則會在 func1(),func2(),func3() 中都找不到對應(yīng)的 catch 匹配,直到 main 函數(shù)才能找到對應(yīng)的匹配,然后輸出:

catch main
end main

如果將 main 函數(shù)中的 catch 捕獲類型也修改為:

catch(void *)

結(jié)果為:

terminate called after throwing an instance of 'double'
 
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

此時系統(tǒng)就會調(diào)用系統(tǒng)函數(shù),使程序終止。

拋出類型聲明

為了增強程序的可讀性,可以在函數(shù)聲明時就列出所有可能拋出的異常類型

void func() throw (A,B,C); ? ? // 表明該函數(shù)只會拋出 A,B,C 及其子類型的異常

如果在函數(shù)聲明時沒有聲明可能拋出的異常類型,則函數(shù)可以拋出任意類型的異常

不拋出任何類型異常的函數(shù),可以聲明為:

void func() throw();

如果一個函數(shù)拋出了拋出類型聲明中所不允許的異常,unexpected 函數(shù)被調(diào)用,啟用 terminal 函數(shù)中止程序

棧自旋

異常被拋出后,從進入 try 塊起,到異常被拋擲前,這期間在棧上的構(gòu)造的所有對象,都會被自動析構(gòu)

析構(gòu)的順序與構(gòu)造的順序相反。這一過程稱為棧的解旋

而堆上的空間,則會泄漏

#include <iostream>
?
using namespace std;
?
class A
{
public:
? ? A(){ cout<<"A()"<<endl; }
? ? ~A(){ cout<<"~A()"<<endl; }
};
?
int func1()
{
? ? A a;
? ? if(1)
? ? ? ? throw('a');
? ? return 0;
}
?
int func2()
{
? ? A b;
? ? func1();
? ? return 1;
}
?
int main()
{
? ? try{
? ? ? ? func2();
? ? }catch(int x){
? ? ? ? cout<<"x"<<endl;
? ? }catch(double y){
? ? ? ? cout<<"y"<<endl;
? ? }catch(...){
? ? ? ? cout<<"no x, no y"<<endl;
? ? }
? ? return 0;
}

結(jié)果為:

A()
A()
~A()
~A()
no x, no y

如果 throw 的是一個類對象:

#include <iostream>
?
using namespace std;
?
class A
{
public:
? ? A(){ cout<<"A()"<<endl; }
? ? A(const A &obj){ cout<<"A(const A &obj)"<<endl; }
? ? ~A(){ cout<<"~A()"<<endl; }
};
?
int func1()
{
? ? A a;
? ? if(1)
? ? ? ? throw(a);
? ? return 0;
}
?
int func2()
{
? ? func1();
? ? return 1;
}
?
int main()
{
? ? try{
? ? ? ? func2();
? ? }catch(int x){
? ? ? ? cout<<"x"<<endl;
? ? }catch(double y){
? ? ? ? cout<<"y"<<endl;
? ? }catch(const A &a){
? ? ? ? cout<<"no x, no y"<<endl;
? ? }
? ? return 0;
}

結(jié)果為:

A()
A(const A &obj)
~A()
no x, no y
~A()

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Qt繪制時鐘效果

    Qt繪制時鐘效果

    這篇文章主要為大家詳細介紹了Qt繪制時鐘效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • C++?Boost?ProgramOptions超詳細講解

    C++?Boost?ProgramOptions超詳細講解

    Boost是為C++語言標準庫提供擴展的一些C++程序庫的總稱。Boost庫是一個可移植、提供源代碼的C++庫,作為標準庫的后備,是C++標準化進程的開發(fā)引擎之一,是為C++語言標準庫提供擴展的一些C++程序庫的總稱
    2022-11-11
  • 解析C++編程中virtual聲明的虛函數(shù)以及單個繼承

    解析C++編程中virtual聲明的虛函數(shù)以及單個繼承

    這篇文章主要介紹了C++編程中virtual聲明的虛函數(shù)以及單個繼承,剖析虛函數(shù)和單個基類所能夠繼承的成員,要的朋友可以參考下
    2016-01-01
  • C++的template模板中class與typename關(guān)鍵字的區(qū)別分析

    C++的template模板中class與typename關(guān)鍵字的區(qū)別分析

    這篇文章中我們來談一談C++的template模板中class與typename關(guān)鍵字的區(qū)別分析,同時會講到嵌套從屬名稱時的一些注意點,需要的朋友可以參考下
    2016-06-06
  • C++實現(xiàn)簡易的彈球小游戲

    C++實現(xiàn)簡易的彈球小游戲

    這篇文章主要為大家詳細介紹了C++實現(xiàn)簡易的彈球小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • 構(gòu)造函數(shù)定義為private或者protected的好處

    構(gòu)造函數(shù)定義為private或者protected的好處

    從語法上來講,一個函數(shù)被聲明為protected或者private,那么這個函數(shù)就不能從“外部”直接被調(diào)用了。對于protected的函數(shù),子類的“內(nèi)部”的其他函數(shù)可以調(diào)用之。而對于private的函數(shù),只能被本類“內(nèi)部”的其他函數(shù)說調(diào)用
    2013-10-10
  • 五個嵌入式C語言中的實用技巧分享

    五個嵌入式C語言中的實用技巧分享

    這篇文章主要和大家分享一下五個嵌入式C語言中的實用技巧,文中的示例代碼講解詳細,對我們學習C語言有一定的幫助,需要的可以參考一下
    2022-12-12
  • C++?計算時間差的五種方法小結(jié)

    C++?計算時間差的五種方法小結(jié)

    本文主要介紹了C++?計算時間差的五種方法小結(jié),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-04-04
  • C語言的字符函數(shù)和字符串函數(shù)詳解

    C語言的字符函數(shù)和字符串函數(shù)詳解

    這篇文章主要為大家詳細介紹了C語言的字符函數(shù)和字符串函數(shù),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • c++統(tǒng)計文件中字符個數(shù)代碼匯總

    c++統(tǒng)計文件中字符個數(shù)代碼匯總

    本文給大家匯總介紹了3種使用C++實現(xiàn)統(tǒng)計文件中的字符個數(shù)的方法,非常的簡單實用,有需要的小伙伴可以參考下。
    2015-09-09

最新評論