C++ 中try finally關(guān)鍵字詳解
try-finally語句是Microsoft對C和C++語言的擴(kuò)展,它能使32位的目標(biāo)程序在異常出現(xiàn)時,有效保證一些資源能夠被及時清除,這些資源的清除任務(wù)可以包括例如內(nèi)存的釋放,文件的關(guān)閉,文件句柄的釋放等等。try-finally語句特別適合這樣的情況下使用,例如一個例程(函數(shù))中,有幾個地方需要檢測一個錯誤,并且在錯誤出現(xiàn)時,函數(shù)可能提前返回。
#include <windows.h>
#include <stdio.h>
try-finally語句的語法與try-except很類似,稍有不同的是,__finally后面沒有一個表達(dá)式,這是因?yàn)閠ry- finally語句的作用不是用于異常處理,所以它不需要一個表達(dá)式來判斷當(dāng)前異常錯誤的種類。另外,與try-except語句類似,try- finally也可以是多層嵌套的,并且一個函數(shù)內(nèi)可以有多個try-finally語句,不管它是嵌套的,或是平行的。當(dāng)然,try-finally多層嵌套也可以是跨函數(shù)的。這里不一一列出示例,大家可以自己測試一番。
另外,對于上面示例程序的運(yùn)行結(jié)果,是不是覺得有點(diǎn)意料之外呢?因?yàn)?__finally塊中的put(“__finally塊中”)語句也被執(zhí)行了。是的,沒錯!這就是try-finally語句最具有魔幻能力的地方,即 “不管在何種情況下,在離開當(dāng)前的作用域時,finally塊區(qū)域內(nèi)的代碼都將會被執(zhí)行到”。呵呵!這的確是很厲害吧!為了驗(yàn)證這條規(guī)則,下面來看一個更典型示例,代碼如下:
#include <stdio.h> void main() { puts(“hello”); __try { puts(“__try塊中”); // 注意,下面return語句直接讓函數(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í)行的流程時,無外乎三種情況。第一種就是順序執(zhí)行到__finally塊區(qū)域內(nèi)的代碼,這種情況很簡單,容易理解;第二種就是goto語句或return語句引發(fā)的程序控制流離開當(dāng)前__try塊作用域時,系統(tǒng)自動完成對__finally塊代碼的調(diào)用;第三種就是由于在__try塊中出現(xiàn)異常時,導(dǎo)致程序控制流離開當(dāng)前__try塊作用域,這種情況下也是由系統(tǒng)自動完成對__finally塊的調(diào)用。無論是第 2種,還是第3種情況,毫無疑問,它們都會引起很大的系統(tǒng)開銷,編譯器在編譯此類程序代碼時,它會為這兩種情況準(zhǔn)備很多的額外代碼。一般第2種情況,被稱為“局部展開(LocalUnwinding)”;第3種情況,被稱為“全局展開(GlobalUnwinding)”。在后面闡述SEH實(shí)現(xiàn)的時候會詳細(xì)分析到這一點(diǎn)。
第3種情況,也即由于出現(xiàn)異常而導(dǎo)致的“全局展開”,對于程序員而言,這也許是無法避免的,因?yàn)槟阍诶卯惓L幚頇C(jī)制提高程序可靠健壯性的同時,不可避免的會引起性能上其它的一些開銷。呵呵!這世界其實(shí)也算瞞公平的,有得必有失。
但是,對于第2種情況,程序員完全可以有效地避免它,避免“局部展開”引起的不必要的額外開銷。實(shí)際這也是與結(jié)構(gòu)化程序設(shè)計(jì)思想相一致的,也即一個程序模塊應(yīng)該只有一個入口和一個出口,程序模塊內(nèi)盡量避免使用goto語句等。但是,話雖如此,有時為了提高程序的可讀性,程序員在編寫代碼時,有時可能不得不采用一些與結(jié)構(gòu)化程序設(shè)計(jì)思想相悖的做法,例如,在一個函數(shù)中,可能有多處的return語句。針對這種情況,SEH提供了一種非常有效的折衷方案,那就是__leave關(guān)鍵字所起的作用,它既具有像goto語句和return語句那樣類似的作用(由于檢測到某個程序運(yùn)行中的錯誤,需要馬上離開當(dāng)前的 __try塊作用域),但是又避免了“局部展開” 的額外開銷。還是看個例子吧!代碼如下:
#include <stdio.h> void test() { puts(“hello”); __try { int* p; puts(“__try塊中”); // 直接跳出當(dāng)前的__try作用域 __leave; p = 0; *p = 25; } __finally { // 這里會被執(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)知識,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對我們網(wǎng)站的支持!
上一篇:6個變態(tài)的C語言Hello World程序
欄 目:C語言
下一篇:淺析C/C++中動態(tài)鏈接庫的創(chuàng)建和調(diào)用
本文標(biāo)題:C++ 中try finally關(guān)鍵字詳解
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/2303.html
您可能感興趣的文章
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言中對數(shù)函數(shù)的表達(dá)式 c語言中對數(shù)怎么表達(dá)
- 04-02c語言沒有round函數(shù) round c語言
- 04-02C語言中怎么打出三角函數(shù) c語言中怎么打出三角函數(shù)的值
- 01-10深入理解C++中常見的關(guān)鍵字含義
- 01-10使用C++實(shí)現(xiàn)全排列算法的方法詳解
- 01-10深入Main函數(shù)中的參數(shù)argc,argv的使用詳解
- 01-10APUE筆記之:進(jìn)程環(huán)境詳解
- 01-10c++中inline的用法分析
- 01-10如何尋找數(shù)組中的第二大數(shù)


閱讀排行
本欄相關(guān)
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言的正則匹配函數(shù) c語言正則表達(dá)
- 04-02c語言用函數(shù)寫分段 用c語言表示分段
- 04-02c語言中對數(shù)函數(shù)的表達(dá)式 c語言中對
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數(shù) c語言中怎
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
隨機(jī)閱讀
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 01-10delphi制作wav文件的方法
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 04-02jquery與jsp,用jquery
- 01-11ajax實(shí)現(xiàn)頁面的局部加載
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05織夢dedecms什么時候用欄目交叉功能?