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

C++拋出和接收異常的順序

 更新時間:2020年08月12日 10:18:23   作者:Dabelv  
這篇文章主要介紹了C++拋出和接收異常的順序,幫助大家更好的理解和學(xué)習(xí)C++,感興趣的朋友可以了解下

異常(exception)是C++語言引入的錯誤處理機(jī)制。它 采用了統(tǒng)一的方式對程序的運行時錯誤進(jìn)行處理,具有標(biāo)準(zhǔn)化、安全和高效的特點。C++為了實現(xiàn)異常處理,引入了三個關(guān)鍵字:try、throw、catch。異常由throw拋出,格式為throw[expression],由catch捕捉。Try語句塊是可能拋出異常的語句塊,它通常和一個或多個catch語句塊連續(xù)出現(xiàn)。

try語句塊和catch語句塊必須相互配合,以下三種情況都會導(dǎo)致編譯錯誤:

 (1)只有try語句塊而沒有catch語句塊,或者只有catch語句塊而沒有try語句塊;
 (2)在try語句塊和catch語句塊之間夾雜有其他語句;
 (3)當(dāng)try語句塊后跟有多個catch語句塊時,catch語句塊之間夾雜有其他語句;
 (4)同一種數(shù)據(jù)類型的傳值catch分支與傳引用catch分支不能同時出現(xiàn)。

在拋出和接收異常的過程中,我們還要注意以下幾點。

1.被拋出的異常對象什么時候被銷毀?

用throw語句拋出一個對象時,會構(gòu)造一個新的對象,這個對象就是異常對象。該對象的生命周期從被拋出開始計算,一直到被某個catch語句捕捉,就會在該catch語句塊執(zhí)行完畢后被銷毀??疾烊缦鲁绦?。

#include <iostream>
using namespace std;

class ExClass
{
 int num;
public:
 ExClass(int i)
 {
 cout<<"Constructing exception object with num="<<i<<endl;
 num=i;
 }
 ExClass(ExClass& e)
 {
 cout<<"Copy Constructing exception object with num="<<e.num+1<<endl;
 num=e.num+1;
 }
 ~ExClass()
 {
 cout<<"Destructing exception object with num="<<num<<endl;
 }
 void show()
 {
 cout<<"the number is "<<num<<endl;
 }
};

int main() 
{
 ExClass obj(99);
 try
 {
 throw obj;   //導(dǎo)致輸出:Constructing exception object with num=100
 }
 catch(double f) 
 {
 cout<<"exception catched"<<endl;
 }
 //導(dǎo)致輸出:Constructing exception object with num=101
 catch(ExClass e) 
 {
 e.show();
 }
 cout<<"after catch"<<endl;
}

程序輸出結(jié)果是:

Constructing exception object with num=99
Copy Constructing exception object with num=100
Copy Constructing exception object with num=101
the number is 101
Destructing exception object with num=101
Destructing exception object with num=100
after catch
Destructing exception object with num=99

用throw語句拋出一個對象時,會構(gòu)造一個新的對象,這個對象就是異常對象。該對象的生命周期從被拋出時開始計算,一直到被某個catch語句捕獲,就會在該catch語句塊執(zhí)行完畢后被銷毀。在上面的程序中,異常對象的num值為100,“Destructing exception object with num=100”這句話在“after catch”之前輸出,正好說明異常對象的銷毀時間是在它被捕獲的catch塊執(zhí)行之后。

所以的catch分支在執(zhí)行時類似一次函數(shù)調(diào)用,catch 的參數(shù)相當(dāng)于函數(shù)的形參,而被拋出的異常對象相當(dāng)于函數(shù)調(diào)用時的實參。當(dāng)形參與實參成功匹配時,就說明異常被某個catch分支所捕獲。catch后面的參數(shù)只能采用傳值、傳引用和傳指針三種方式,如果采用傳值方式,則會生成實參的一個副本,如果實參是一個對象,就會導(dǎo)致構(gòu)造函數(shù)被調(diào)用。在上面的程序中,執(zhí)行catch(ExClass e) 語句就是利用異常對象構(gòu)造一個對象e,因此會調(diào)用拷貝構(gòu)造函數(shù)。
 要注意的是:同一種數(shù)據(jù)類型的傳值catch分支和傳引用catch分支不能同時出現(xiàn)。

2.異常如果在當(dāng)前函數(shù)沒有被捕獲會發(fā)生什么?

在某些情況下,可能所有的catch分支都無法捕獲到拋出的異常,這將導(dǎo)致當(dāng)前函數(shù)執(zhí)行的結(jié)束,并返回到主調(diào)函數(shù)中。在主調(diào)函數(shù)中,將繼續(xù)以上的捕捉異常的過程,直到異常被捕捉或最終結(jié)束整個程序。考察如下程序。

#include <iostream>
using namespace std;

class ExClass
{
 int num;
public:
 ExClass(int i)
 {
 cout<<"Constructing exception object with num="<<i<<endl;
 num=i;
 }
 ExClass(ExClass& e)
 {
 cout<<"Copy Constructing exception object with num="<<e.num+1<<endl;
 num=e.num+1;
 }
 ~ExClass()
 {
 cout<<"Destructing exception object with num="<<num<<endl;
 }
 void show()
 {
 cout<<"the number is "<<num<<endl;
 }
};

void throwExFunc()
{
 try{
 throw ExClass(199);
 }
 catch(double f){
 cout<<"double exception catched"<<endl;
 }
 cout<<"exit throwExFunc()"<<endl;
}

int main()
{
 try
 {
 throwExFunc();
 }
 catch(ExClass e)
 {
 e.show();
 }
 catch(...)
 {
 cout<<"all will fall in"<<endl;
 }
 cout<<"continue to execute"<<endl;
}

程序的輸出結(jié)果:

Constructing exception object with num=199
Copy Constructing exception object with num=200
the number is 200
Destructing exception object with num=200
Destructing exception object with num=199
continue to execute

從程序的結(jié)果可以看出:

 (1)被拋出的異常對象的num值為199,由于它沒有在函數(shù)throwExFunc()中被捕捉,所以它導(dǎo)致了throwExFunc()的執(zhí)行結(jié)束(否則會輸出:exit throwExFunc())。在main()函數(shù)中,catch(ExClass e)捕獲了異常對象,通過復(fù)制構(gòu)造函數(shù)產(chǎn)生對象e,e的num值為200,catch語句塊運行完結(jié)束后,對象e首先被銷毀,緊接著銷毀異常對象。在這之后,程序繼續(xù)運行,輸出:continue to execute。

(2)catch(…)的意思是可以捕獲所有類型的異常。不提倡隨意地使用catch(…),因為這會導(dǎo)致異常類型的不精確處理,并降低程序的運行效率。但是,在程序的開發(fā)階段,catch(…)還是有用的,因為如果在精心安排異常捕獲之后,還是進(jìn)入了catch(…)語句塊,說明前面的代碼存在缺陷,需要進(jìn)一步改正。

(3)在捕捉異常對象時,還可以采用傳引用的方式,例如把catch語句寫成catch(ExClass& e),這樣就可以不必產(chǎn)生異常對象的副本,減少程序的運行開銷,提高運行效率。

(4)在拋出異常時,還可以拋出一個指針。當(dāng)然這種做法并不總是安全的。如果要確保安全,應(yīng)該將指針指向全局(靜態(tài))對象的指針或指向動態(tài)申請的空間,或者被拋出的指針在本函數(shù)內(nèi)被捕獲。否則,利用一個被拋出的指向已經(jīng)被銷毀的對象指針很危險。如果實在要用,首先,必須保證對象的析構(gòu)函數(shù)不能對對象的內(nèi)容作損傷性的修改,其次,對象的空間沒有被其他新產(chǎn)生的變量覆蓋。也就說,盡管對象被釋放,但它的有效內(nèi)容依然保留在棧中。

以上就是C++拋出和接收異常的順序的詳細(xì)內(nèi)容,更多關(guān)于C++拋出和接收異常的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • c++實現(xiàn)合并文件以及拆分實例代碼

    c++實現(xiàn)合并文件以及拆分實例代碼

    這篇文章主要介紹了c++實現(xiàn)合并文件以及拆分實例代碼,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下
    2018-01-01
  • C++運算符重載限制介紹

    C++運算符重載限制介紹

    這篇文章主要介紹了C++運算符重載限制,關(guān)于運算符的重載并不是隨心所欲的。C++給出了一些限制,從而保證了規(guī)范,以及程序運行的準(zhǔn)確性,下面來了解C++運算符重載限制的詳細(xì)內(nèi)容吧,需要的朋友也可以參考一下
    2022-01-01
  • 深入解析最長公共子串

    深入解析最長公共子串

    本篇文章是對最長公共子串進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • STL中vector的使用你了解嗎

    STL中vector的使用你了解嗎

    這篇文章主要為大家詳細(xì)介紹了STL中vector的使用,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • 使用C語言編寫圣誕表白程序

    使用C語言編寫圣誕表白程序

    圣誕節(jié)快到了,讓我們用C語言制作一個圣誕表白程序吧,下面通過本文學(xué)習(xí)下實現(xiàn)代碼
    2016-12-12
  • Qt顯示QImage圖像在label上,并保持自適應(yīng)大小問題

    Qt顯示QImage圖像在label上,并保持自適應(yīng)大小問題

    這篇文章主要介紹了Qt顯示QImage圖像在label上,并保持自適應(yīng)大小問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • 淺談C語言中的強(qiáng)符號、弱符號、強(qiáng)引用和弱引用

    淺談C語言中的強(qiáng)符號、弱符號、強(qiáng)引用和弱引用

    這篇文章主要介紹了C語言中的強(qiáng)符號、弱符號、強(qiáng)引用和弱引用的定義及相關(guān)內(nèi)容,非常的簡單易懂,有需要的朋友可以參考下
    2014-10-10
  • C++棧實現(xiàn)逆波蘭式的應(yīng)用

    C++棧實現(xiàn)逆波蘭式的應(yīng)用

    逆波蘭式指的是操作符在其所控制的操作數(shù)后面的表達(dá)式。本文主要介紹了C++棧實現(xiàn)逆波蘭式的應(yīng)用,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • 基于C++實現(xiàn)三種不同版本的通訊錄

    基于C++實現(xiàn)三種不同版本的通訊錄

    這篇文章主要為大家詳細(xì)介紹了如何通過C++實現(xiàn)三種不同版本的通訊錄(動態(tài)版本、靜態(tài)版本、文件版本),文中的示例代碼講解詳細(xì),希望對大家有所幫助
    2022-11-11
  • 二叉樹遍歷 非遞歸 C++實現(xiàn)代碼

    二叉樹遍歷 非遞歸 C++實現(xiàn)代碼

    對于二叉樹,有前序、中序以及后序三種遍歷方法。因為樹的定義本身就是遞歸定義,因此采用遞歸的方法去實現(xiàn)樹的三種遍歷不僅容易理解而且代碼很簡潔。而對于樹的遍歷若采用非遞歸的方法,就要采用棧去模擬實現(xiàn)
    2013-09-09

最新評論