溫馨提示×

溫馨提示×

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

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

異常處理深度解析(五十八)

發(fā)布時間:2020-08-05 19:01:12 來源:網(wǎng)絡 閱讀:479 作者:上帝之子521 欄目:編程語言

        我們之前學習了異常有關的知識,那么如果在 main 函數(shù)中中拋出異常會發(fā)生什么呢?如果異常不進行處理,最后會傳到哪里呢?如下

異常處理深度解析(五十八)

        下來我們就來做個實驗,代碼如下

#include <iostream>

using namespace std;

class Test
{
public:
    Test()
    {
        cout << "Test()" << endl;
    }
    
    ~Test()
    {
        cout << "~Test()" << endl;
    }
};

int main()
{
    static Test t;
    
    throw 1;
    
    return 0;
}

        我們先來看看 g++ 編譯器是怎樣處理的

異常處理深度解析(五十八)

        我們看到在打印了構造函數(shù)的語句之后,下面還輸出兩句話,那么我們并沒有在程序中定義這樣的輸出啊,這個到底是誰打印出來的呢?我們來看看 BCC 編譯器

異常處理深度解析(五十八)

        在 BCC 編譯器中輸出了下面的一句話,也并不是我們定義的。我們再來看看 vs2010 編譯器

異常處理深度解析(五十八)

        我們看到在 vs2010 編譯器中彈出了一個對話框,我們并沒有編寫相關的代碼。我們來看看編譯器在背后究竟做了哪些事,如果異常無法被處理,terminate() 結束函數(shù)會被自動調(diào)用。默認情況下,terminate() 調(diào)用庫函數(shù) abort() 終止程序,abort() 函數(shù)使得程序執(zhí)行異常而立即退出,C++ 支持替換默認的 terminate() 函數(shù)實現(xiàn)。

        terminate() 函數(shù)的替換:a> 它是自定義一個無返回值無參數(shù)的函數(shù),不能拋出任何異常,必須以某種方式結束當前程序;b> 調(diào)用 set_terminate() 設置自定義的結束函數(shù),參數(shù)類型為 void(*)(),返回值為默認的 terminate() 函數(shù)入口地址。

        下來我們來自定義 terminate() 函數(shù)。

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

using namespace std;

void my_terminate()
{
    cout << "void my_terminate()" << endl;
    exit(1);
}

class Test
{
public:
    Test()
    {
        cout << "Test()" << endl;
    }
    
    ~Test()
    {
        cout << "~Test()" << endl;
    }
};

int main()
{
    set_terminate(my_terminate);
    
    static Test t;
    
    throw 1;
    
    return 0;
}

        我們再來看看編譯結果,先在 g++ 編譯器下

異常處理深度解析(五十八)

        我們看到程序正常運行結束了。我們來分析下,我們在 main 函數(shù)中調(diào)用 set_terminate() 設置結束函數(shù) my_terminate()。在 main 函數(shù)中拋出了一個異常,被結束函數(shù) my_terminate() 捕獲到了,然后執(zhí)行它里面的打印語句,進而執(zhí)行到 exit(1) 正常退出。所以在最后退出的時候會去執(zhí)行析構函數(shù)。我們再來看看 BCC 編譯器呢

異常處理深度解析(五十八)

        我們看到和 g++ 編譯器中的行為是一樣的,再來看看 vs2010 編譯器看看

異常處理深度解析(五十八)

        那么如果在析構函數(shù)中拋出異常會發(fā)生什么情況呢?我們來試試,在上面的程序中的析構函數(shù)拋出一個異常,看看編譯結果

異常處理深度解析(五十八)

        我們看到最后又去調(diào)用內(nèi)置的 Aborted 函數(shù)了。再來看看 BCC 編譯器呢

異常處理深度解析(五十八)

        同樣也是這樣的情況,看看 vs2010 編譯器

異常處理深度解析(五十八)

        我們來分析下,它先是在 main 函數(shù)中拋出異常,然后執(zhí)行到 my_terminate() 函數(shù)中,進而退出(清理一切資源等),在退出的時候又去執(zhí)行析構函數(shù),又再次拋出異常,等于又要再次進行資源的釋放,造成二次釋放了。類似于在操作指針時,二次釋放,所帶來的后果是無法確定的。因此它最后會去調(diào)用庫函數(shù)中的 abort() 函數(shù)。因此,我們在 main 函數(shù)中盡量不要拋出異常。通過對異常的深度學習,總結如下:1、如果異常沒有被處理,最后 terminate() 結束整個程序;2、terminate() 是整個程序釋放系統(tǒng)資源的最后機會;3、結束函數(shù)可以自定義,但不能繼續(xù)拋出異常;4、析構函數(shù)中不能拋出異常,可能導致 terminate() 多次調(diào)用。


        歡迎大家一起來學習 C++ 語言,可以加我QQ:243343083。

向AI問一下細節(jié)

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

AI