我們之前學(xué)習(xí)了異常有關(guān)的知識(shí),那么如果在 main 函數(shù)中中拋出異常會(huì)發(fā)生什么呢?如果異常不進(jìn)行處理,最后會(huì)傳到哪里呢?如下
創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括潘集網(wǎng)站建設(shè)、潘集網(wǎng)站制作、潘集網(wǎng)頁(yè)制作以及潘集網(wǎng)絡(luò)營(yíng)銷策劃等。多年來(lái),我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,潘集網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到潘集省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
下來(lái)我們就來(lái)做個(gè)實(shí)驗(yàn),代碼如下
#includeusing namespace std; class Test { public: Test() { cout << "Test()" << endl; } ~Test() { cout << "~Test()" << endl; } }; int main() { static Test t; throw 1; return 0; }
我們先來(lái)看看 g++ 編譯器是怎樣處理的
我們看到在打印了構(gòu)造函數(shù)的語(yǔ)句之后,下面還輸出兩句話,那么我們并沒有在程序中定義這樣的輸出啊,這個(gè)到底是誰(shuí)打印出來(lái)的呢?我們來(lái)看看 BCC 編譯器
在 BCC 編譯器中輸出了下面的一句話,也并不是我們定義的。我們?cè)賮?lái)看看 vs2010 編譯器
我們看到在 vs2010 編譯器中彈出了一個(gè)對(duì)話框,我們并沒有編寫相關(guān)的代碼。我們來(lái)看看編譯器在背后究竟做了哪些事,如果異常無(wú)法被處理,terminate() 結(jié)束函數(shù)會(huì)被自動(dòng)調(diào)用。默認(rèn)情況下,terminate() 調(diào)用庫(kù)函數(shù) abort() 終止程序,abort() 函數(shù)使得程序執(zhí)行異常而立即退出,C++ 支持替換默認(rèn)的 terminate() 函數(shù)實(shí)現(xiàn)。
terminate() 函數(shù)的替換:a> 它是自定義一個(gè)無(wú)返回值無(wú)參數(shù)的函數(shù),不能拋出任何異常,必須以某種方式結(jié)束當(dāng)前程序;b> 調(diào)用 set_terminate() 設(shè)置自定義的結(jié)束函數(shù),參數(shù)類型為 void(*)(),返回值為默認(rèn)的 terminate() 函數(shù)入口地址。
下來(lái)我們來(lái)自定義 terminate() 函數(shù)。
#include#include #include 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; }
我們?cè)賮?lái)看看編譯結(jié)果,先在 g++ 編譯器下
我們看到程序正常運(yùn)行結(jié)束了。我們來(lái)分析下,我們?cè)?main 函數(shù)中調(diào)用 set_terminate() 設(shè)置結(jié)束函數(shù) my_terminate()。在 main 函數(shù)中拋出了一個(gè)異常,被結(jié)束函數(shù) my_terminate() 捕獲到了,然后執(zhí)行它里面的打印語(yǔ)句,進(jìn)而執(zhí)行到 exit(1) 正常退出。所以在最后退出的時(shí)候會(huì)去執(zhí)行析構(gòu)函數(shù)。我們?cè)賮?lái)看看 BCC 編譯器呢
我們看到和 g++ 編譯器中的行為是一樣的,再來(lái)看看 vs2010 編譯器看看
那么如果在析構(gòu)函數(shù)中拋出異常會(huì)發(fā)生什么情況呢?我們來(lái)試試,在上面的程序中的析構(gòu)函數(shù)拋出一個(gè)異常,看看編譯結(jié)果
我們看到最后又去調(diào)用內(nèi)置的 Aborted 函數(shù)了。再來(lái)看看 BCC 編譯器呢
同樣也是這樣的情況,看看 vs2010 編譯器
我們來(lái)分析下,它先是在 main 函數(shù)中拋出異常,然后執(zhí)行到 my_terminate() 函數(shù)中,進(jìn)而退出(清理一切資源等),在退出的時(shí)候又去執(zhí)行析構(gòu)函數(shù),又再次拋出異常,等于又要再次進(jìn)行資源的釋放,造成二次釋放了。類似于在操作指針時(shí),二次釋放,所帶來(lái)的后果是無(wú)法確定的。因此它最后會(huì)去調(diào)用庫(kù)函數(shù)中的 abort() 函數(shù)。因此,我們?cè)?main 函數(shù)中盡量不要拋出異常。通過對(duì)異常的深度學(xué)習(xí),總結(jié)如下:1、如果異常沒有被處理,最后 terminate() 結(jié)束整個(gè)程序;2、terminate() 是整個(gè)程序釋放系統(tǒng)資源的最后機(jī)會(huì);3、結(jié)束函數(shù)可以自定義,但不能繼續(xù)拋出異常;4、析構(gòu)函數(shù)中不能拋出異常,可能導(dǎo)致 terminate() 多次調(diào)用。
歡迎大家一起來(lái)學(xué)習(xí) C++ 語(yǔ)言,可以加我QQ:243343083。