中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

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

發布時間:2020-08-05 19:01:12 來源:網絡 閱讀:480 作者:上帝之子521 欄目:編程語言

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

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

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

#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++ 編譯器是怎樣處理的

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

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

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

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

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

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

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

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

#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 函數中調用 set_terminate() 設置結束函數 my_terminate()。在 main 函數中拋出了一個異常,被結束函數 my_terminate() 捕獲到了,然后執行它里面的打印語句,進而執行到 exit(1) 正常退出。所以在最后退出的時候會去執行析構函數。我們再來看看 BCC 編譯器呢

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

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

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

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

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

        我們看到最后又去調用內置的 Aborted 函數了。再來看看 BCC 編譯器呢

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

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

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

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


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

向AI問一下細節

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

AI

西藏| 渝中区| 鄂托克旗| 固安县| 疏勒县| 秦安县| 桂东县| 板桥市| 渝中区| 铜山县| 武平县| 思南县| 商洛市| 新平| 牡丹江市| 双流县| 安化县| 阳江市| 大英县| 凤山县| 桓台县| 象山县| 长岭县| 沅江市| 金溪县| 敖汉旗| 伊金霍洛旗| 天台县| 依兰县| 喜德县| 濮阳市| 育儿| 龙川县| 仙居县| 沁水县| 吴旗县| 怀宁县| 玛曲县| 壤塘县| 林西县| 咸宁市|