溫馨提示×

溫馨提示×

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

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

函數(shù)的異常規(guī)格說明(五十九)

發(fā)布時(shí)間:2020-07-08 14:12:22 來源:網(wǎng)絡(luò) 閱讀:850 作者:上帝之子521 欄目:編程語言

        我們在進(jìn)行異常分析的時(shí)候,如何判斷一個(gè)函數(shù)是否會拋出異常,以及拋出哪些異常呢?C++ 提供語法用于聲明函數(shù)所拋出的異常,異常聲明作為函數(shù)聲明的修飾符,寫在參數(shù)列表后面。如下

函數(shù)的異常規(guī)格說明(五十九)

        函數(shù)異常規(guī)格說明的意義是:a> 提供商函數(shù)調(diào)用者必須做好異常處理的準(zhǔn)備;b> 提供函數(shù)的維護(hù)者不要拋出其他異常;c> 異常規(guī)格說明是函數(shù)接口的一部分。那么如果拋出的異常不在聲明列表中會發(fā)生什么?

        下面我們還是以代碼為例來進(jìn)行說明

#include <iostream>

using namespace std;

void func() throw(int)
{
    cout << "func()" << endl;
    
    throw 'c';
}

int main()
{
    try
    {
        func();
    }
    catch(int)
    {
        cout << "catch(int)" << endl;
    }
    catch(char)
    {
        cout << "catch(char)" << endl;
    }
    
    return 0;
}

        我們在 func 函數(shù)的后面只聲明有可能會拋出 int 類型的異常,實(shí)際我們拋出的是字符型異常,我們來看看在 main 函數(shù)中的 catch(char) 語句塊能捕獲到嗎?先來看看 g++ 編譯器下是怎樣的

函數(shù)的異常規(guī)格說明(五十九)

        運(yùn)行的結(jié)果是沒有捕獲到 char 類型的異常,調(diào)用了 Aborted 函數(shù)。我們再用 BCC 編譯器試試

函數(shù)的異常規(guī)格說明(五十九)

        我們再來試試 vs2010 編譯器

函數(shù)的異常規(guī)格說明(五十九)

        我們看到在 vs2010 中捕獲到了拋出的異常。如果函數(shù)拋出的異常不在規(guī)格說明中,全局 unexpected() 被調(diào)用。默認(rèn)的 unexpected() 函數(shù)會調(diào)用全局的 terminate() 函數(shù),我們可以自定義函數(shù)替換默認(rèn)的 unexpected() 函數(shù)實(shí)現(xiàn)。注意:不是所有的 C++ 編譯器都支持這個(gè)標(biāo)準(zhǔn)行為。

        下來我們來說說 unexpected() 函數(shù)的替換:a> 自定義一個(gè)無返回值參數(shù)的函數(shù),能夠再次拋出異常。當(dāng)異常符合觸發(fā)函數(shù)的異常規(guī)格說明時(shí),恢復(fù)程序執(zhí)行。否則,調(diào)用全局 terminate() 函數(shù)結(jié)束程序;b> 調(diào)用 set_unexpected() 設(shè)置自定義的異常函數(shù),參數(shù)類型為 void(*)(),返回值為默認(rèn)的 unexpected() 函數(shù)入口地址。

        我們來看看自定義 unexpected() 函數(shù)的代碼是怎么寫的

#include <iostream>
#include <cstdlib>
#include <exception>

using namespace std;

void my_unexpected()
{
    cout << "void my_unexpected()" << endl;
    
    throw 1;
}

void func() throw(int)
{
    cout << "func()" << endl;
    
    throw 'c';
}

int main()
{
    set_unexpected(my_unexpected);
    
    try
    {
        func();
    }
    catch(int)
    {
        cout << "catch(int)" << endl;
    }
    catch(char)
    {
        cout << "catch(char)" << endl;
    }
    
    return 0;
}

        我們先來分析下,在 func 函數(shù)中聲明的異常是 int 類型的,但是拋出的 char 類型的。因此編譯器會調(diào)用我們設(shè)置的 my_unexpected() 函數(shù),在 my_unexpected() 中又拋出了一個(gè) int 類型的異常,因此便會被 main 函數(shù)中的 catch(int) 捕獲到,輸出 catch(int) 語句。我們來看看在 g++ 編譯器中是怎樣的

函數(shù)的異常規(guī)格說明(五十九)

        跟我們分析的是一致的,再來看看 vs2010 編譯器是怎樣的

函數(shù)的異常規(guī)格說明(五十九)

        它還是我行我素,沒一點(diǎn)變化。這便是我們之前說的不是所有的 C++ 編譯器都支持這個(gè)標(biāo)準(zhǔn)行為。通過對異常規(guī)格說明的學(xué)習(xí),總結(jié)如下:1、C++ 中的函數(shù)可以聲明異常規(guī)格說明,異常規(guī)格說明可以看做接口的一部分;2、函數(shù)拋出的異常不在規(guī)格說明中,unexpected() 被調(diào)用;3、unexpected() 中能夠再次拋出異常:異常能夠匹配則恢復(fù)程序的執(zhí)行,否則調(diào)用 terminate() 結(jié)束程序。


        歡迎大家一起來學(xué)習(xí) C++ 語言,可以加我QQ:243343083。

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

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

AI