您好,登錄后才能下訂單哦!
我們之前學習了異常有關的知識,那么如果在 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。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。