C++ 中try finally關(guān)鍵字詳解
try-finally語(yǔ)句是Microsoft對(duì)C和C++語(yǔ)言的擴(kuò)展,它能使32位的目標(biāo)程序在異常出現(xiàn)時(shí),有效保證一些資源能夠被及時(shí)清除,這些資源的清除任務(wù)可以包括例如內(nèi)存的釋放,文件的關(guān)閉,文件句柄的釋放等等。try-finally語(yǔ)句特別適合這樣的情況下使用,例如一個(gè)例程(函數(shù))中,有幾個(gè)地方需要檢測(cè)一個(gè)錯(cuò)誤,并且在錯(cuò)誤出現(xiàn)時(shí),函數(shù)可能提前返回。
#include <windows.h>
#include <stdio.h>
try-finally語(yǔ)句的語(yǔ)法與try-except很類似,稍有不同的是,__finally后面沒(méi)有一個(gè)表達(dá)式,這是因?yàn)閠ry- finally語(yǔ)句的作用不是用于異常處理,所以它不需要一個(gè)表達(dá)式來(lái)判斷當(dāng)前異常錯(cuò)誤的種類。另外,與try-except語(yǔ)句類似,try- finally也可以是多層嵌套的,并且一個(gè)函數(shù)內(nèi)可以有多個(gè)try-finally語(yǔ)句,不管它是嵌套的,或是平行的。當(dāng)然,try-finally多層嵌套也可以是跨函數(shù)的。這里不一一列出示例,大家可以自己測(cè)試一番。
另外,對(duì)于上面示例程序的運(yùn)行結(jié)果,是不是覺(jué)得有點(diǎn)意料之外呢?因?yàn)?__finally塊中的put(“__finally塊中”)語(yǔ)句也被執(zhí)行了。是的,沒(méi)錯(cuò)!這就是try-finally語(yǔ)句最具有魔幻能力的地方,即 “不管在何種情況下,在離開(kāi)當(dāng)前的作用域時(shí),finally塊區(qū)域內(nèi)的代碼都將會(huì)被執(zhí)行到”。呵呵!這的確是很厲害吧!為了驗(yàn)證這條規(guī)則,下面來(lái)看一個(gè)更典型示例,代碼如下:
#include <stdio.h> void main() { puts(“hello”); __try { puts(“__try塊中”); // 注意,下面return語(yǔ)句直接讓函數(shù)返回了 return; } __finally { puts(“__finally塊中”); } puts(“world”); } 上面的程序運(yùn)行結(jié)果如下: hello __try塊中 __finally塊中 Press any key to continue void main() { puts(“hello”); __try { puts(“__try塊中”); } // 注意,這里不是__except塊,而是__finally取代 __finally { puts(“__finally塊中”); } puts(“world”); }
上面的程序運(yùn)行結(jié)果如下:
hello
__try塊中
__finally塊中
world
Press any key to continue
總結(jié)__finally塊被執(zhí)行的流程時(shí),無(wú)外乎三種情況。第一種就是順序執(zhí)行到__finally塊區(qū)域內(nèi)的代碼,這種情況很簡(jiǎn)單,容易理解;第二種就是goto語(yǔ)句或return語(yǔ)句引發(fā)的程序控制流離開(kāi)當(dāng)前__try塊作用域時(shí),系統(tǒng)自動(dòng)完成對(duì)__finally塊代碼的調(diào)用;第三種就是由于在__try塊中出現(xiàn)異常時(shí),導(dǎo)致程序控制流離開(kāi)當(dāng)前__try塊作用域,這種情況下也是由系統(tǒng)自動(dòng)完成對(duì)__finally塊的調(diào)用。無(wú)論是第 2種,還是第3種情況,毫無(wú)疑問(wèn),它們都會(huì)引起很大的系統(tǒng)開(kāi)銷,編譯器在編譯此類程序代碼時(shí),它會(huì)為這兩種情況準(zhǔn)備很多的額外代碼。一般第2種情況,被稱為“局部展開(kāi)(LocalUnwinding)”;第3種情況,被稱為“全局展開(kāi)(GlobalUnwinding)”。在后面闡述SEH實(shí)現(xiàn)的時(shí)候會(huì)詳細(xì)分析到這一點(diǎn)。
第3種情況,也即由于出現(xiàn)異常而導(dǎo)致的“全局展開(kāi)”,對(duì)于程序員而言,這也許是無(wú)法避免的,因?yàn)槟阍诶卯惓L幚頇C(jī)制提高程序可靠健壯性的同時(shí),不可避免的會(huì)引起性能上其它的一些開(kāi)銷。呵呵!這世界其實(shí)也算瞞公平的,有得必有失。
但是,對(duì)于第2種情況,程序員完全可以有效地避免它,避免“局部展開(kāi)”引起的不必要的額外開(kāi)銷。實(shí)際這也是與結(jié)構(gòu)化程序設(shè)計(jì)思想相一致的,也即一個(gè)程序模塊應(yīng)該只有一個(gè)入口和一個(gè)出口,程序模塊內(nèi)盡量避免使用goto語(yǔ)句等。但是,話雖如此,有時(shí)為了提高程序的可讀性,程序員在編寫(xiě)代碼時(shí),有時(shí)可能不得不采用一些與結(jié)構(gòu)化程序設(shè)計(jì)思想相悖的做法,例如,在一個(gè)函數(shù)中,可能有多處的return語(yǔ)句。針對(duì)這種情況,SEH提供了一種非常有效的折衷方案,那就是__leave關(guān)鍵字所起的作用,它既具有像goto語(yǔ)句和return語(yǔ)句那樣類似的作用(由于檢測(cè)到某個(gè)程序運(yùn)行中的錯(cuò)誤,需要馬上離開(kāi)當(dāng)前的 __try塊作用域),但是又避免了“局部展開(kāi)” 的額外開(kāi)銷。還是看個(gè)例子吧!代碼如下:
#include <stdio.h> void test() { puts(“hello”); __try { int* p; puts(“__try塊中”); // 直接跳出當(dāng)前的__try作用域 __leave; p = 0; *p = 25; } __finally { // 這里會(huì)被執(zhí)行嗎?當(dāng)然 puts(“__finally塊中”); } puts(“world”); } void main() { __try { test(); } __except(1) { puts(“__except塊中”); } }
上面的程序運(yùn)行結(jié)果如下:
hello
__try塊中
__finally塊中
world
Press any key to continue
以上所述是小編給大家介紹的C++ 中try finally關(guān)鍵字的相關(guān)知識(shí),希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
基于c語(yǔ)言知識(shí)點(diǎn)的補(bǔ)遺介紹
本篇文章是對(duì)c語(yǔ)言知識(shí)點(diǎn)的一些補(bǔ)遺進(jìn)行詳細(xì)的分析介紹,需要的朋友參考下2013-05-05C語(yǔ)言編程簡(jiǎn)單卻重要的數(shù)據(jù)結(jié)構(gòu)順序表全面講解
這篇文章主要為大家介紹了C語(yǔ)言編程中非常簡(jiǎn)單卻又非常重要的數(shù)據(jù)結(jié)構(gòu)順序表的全面講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-10-10C++編程中new運(yùn)算符的使用學(xué)習(xí)教程
這篇文章主要介紹了C++編程中new運(yùn)算符的使用學(xué)習(xí)教程,是C++入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2016-01-01一篇文章帶你了解C++Primer學(xué)習(xí)日記--處理數(shù)據(jù)
今天小編就為大家分享一篇關(guān)于C++對(duì)數(shù)器的使用講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2021-08-08Qt編寫(xiě)提示進(jìn)度條的實(shí)現(xiàn)示例
進(jìn)度條在很地方都可以使用到,Qt自帶的進(jìn)度條或者操作系統(tǒng)的進(jìn)度條樣式,不夠炫,本文就介紹一下Qt編寫(xiě)自定義控件的提示進(jìn)度條的實(shí)現(xiàn)示例,感興趣的可以了解一下2021-12-12C語(yǔ)言編寫(xiě)Linux守護(hù)進(jìn)程實(shí)例
這篇文章主要介紹了C語(yǔ)言編寫(xiě)Linux守護(hù)進(jìn)程實(shí)例,本文講解了守護(hù)進(jìn)程及其特性、守護(hù)進(jìn)程的編程要點(diǎn)、守護(hù)進(jìn)程代碼實(shí)例等內(nèi)容,需要的朋友可以參考下2015-02-02