下載本文檔
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、C+箴言:防止因異常而離開(kāi)析構(gòu)函數(shù)C+ 并不禁止從析構(gòu)函數(shù)中引發(fā)異常,但是這確實(shí)妨礙了實(shí)踐。至于有什么好的理由,考慮: class Widget public:.Widget() . / assume this might emit an exception; void doSomething()std:vector<Widget> v;. / v is automatically destroyed here 當(dāng) vector v 被析構(gòu)時(shí),它有責(zé)任銷毀它包含的所有 Widgets.假設(shè) v 中有十個(gè) Widgets,在銷毀第一個(gè)的時(shí)候,拋出一個(gè)異常。其他 9個(gè) Wid
2、gets 仍然必須被銷毀(否則他們持有的任何資源將被泄漏),所以 v 應(yīng)該調(diào)用它們的析構(gòu)函數(shù)。但是假設(shè)在這個(gè)調(diào)用期間,第二個(gè) Widgets 的析構(gòu)函數(shù)又拋出一個(gè)異?!,F(xiàn)在有兩個(gè)異常同時(shí)在活動(dòng)中,對(duì)于 C+ 來(lái)說(shuō)這太多了。在非常巧合的條件下發(fā)生這樣兩個(gè)同時(shí)活動(dòng)的異常,程序的執(zhí)行會(huì)終止或者引發(fā)未定義行為。在本例中,將引發(fā)未定義行為。與此相同,使用任何標(biāo)準(zhǔn)庫(kù)容器(比如,list,set),任何 TR1中的容器,甚至是一個(gè)數(shù)組,都可能會(huì)引發(fā)未定義問(wèn)題。并非必須是容器或數(shù)組才會(huì)陷入麻煩。程序夭折或未定義行為是析構(gòu)函數(shù)引發(fā)異常的結(jié)果,即使沒(méi)有使用容器或數(shù)組也會(huì)如此。C+ 不喜歡引發(fā)異常的析構(gòu)函數(shù)。 這比
3、較容易理解,但是如果你的析構(gòu)函數(shù)需要執(zhí)行一個(gè)可能失敗而拋出異常的操作,該怎么辦呢?例如,假設(shè)你與一個(gè)數(shù)據(jù)庫(kù)連接類一起工作: class DBConnection public:.static DBConnection create(); / function to return/ DBConnection objects; params/ omitted for simplicity void close(); / close connection; throw an; / exception if closing fails 為了確??蛻舨粫?huì)忘記調(diào)用 DBconnection 對(duì)象
4、的 close,一個(gè)合理的主意是為 DBConnection 建立一個(gè)資源管理類,在它的析構(gòu)函數(shù)中調(diào)用 close.這樣的資源管理類將在以后的文章中探討,但在這里,只要認(rèn)為這樣一個(gè)類的析構(gòu)函數(shù)看起來(lái)像這樣就足夠了: class DBConn / class to manage DBConnectionpublic: / objects.DBConn() / make sure database connections / are always closeddb.close();private:DBConnection db; 它允許客戶像這樣編程: / open a bl
5、ockDBConn dbc(DBConnection:create(); / create DBConnection object/ and turn it over to a DBConn/ object to manage. / use the DBConnection object/ via the DBConn interface / at end of block, the DBConn/ object is destroyed, thus/ automatically calling close on/ the DBConnection object 既然能成功地調(diào)用 close
6、那就好了,但是如果這個(gè)調(diào)用導(dǎo)致了異常,DBConn 的析構(gòu)函數(shù)將散播那個(gè)異常,也就是說(shuō),它將離開(kāi)析構(gòu)函數(shù)。這就產(chǎn)生了問(wèn)題,因?yàn)槲鰳?gòu)函數(shù)拋出了一個(gè)燙手的山芋。有兩個(gè)主要的方法避免這個(gè)麻煩。DBConn 的析構(gòu)函數(shù)能:終止程序 如果 close 拋出異常,調(diào)用 abort。 DBConn:DBConn()try db.close(); catch (.) make log entry that the call to close failed;std:abort(); 如果程序在析構(gòu)過(guò)程遭遇到錯(cuò)誤后不能繼續(xù)運(yùn)行,這就是一個(gè)合理的選擇。它有一個(gè)好處是:如果允許從析構(gòu)函數(shù)散播異??赡軙?huì)引起未
7、定義行為,這樣就能防止它發(fā)生。也就是說(shuō),調(diào)用 abort 就預(yù)先防止了未定義行為。抑制這個(gè)異常 起因于調(diào)用 close: DBConn:DBConn()try db.close(); catch (.) make log entry that the call to close failed; 通常,抑制異常是一個(gè)不好的主意,因?yàn)樗鼤?huì)隱瞞重要的信息某些事情失敗了!可是,有些時(shí)候,抑制異常比冒程序夭折或未定義行為的風(fēng)險(xiǎn)更可取。程序必須能夠在遭遇到錯(cuò)誤并忽略之后還能繼續(xù)可靠地執(zhí)行,這才能成為一個(gè)可行的選擇。這些方法都不太吸引人。它們的問(wèn)題在于程序無(wú)法在第一現(xiàn)場(chǎng)對(duì)引起 close 拋出異常
8、的條件做出回應(yīng)。一個(gè)更好的策略是設(shè)計(jì) DBConn 的接口,以使它的客戶有機(jī)會(huì)對(duì)可能會(huì)發(fā)生的問(wèn)題做出回應(yīng)。例如,DBConn 能夠自己提供一個(gè) close 函數(shù),從而給客戶一個(gè)機(jī)會(huì)去處理從那個(gè)操作中發(fā)出的異常。它還能保持對(duì)它的 DBConnection 是否已被關(guān)閉的跟蹤,如果沒(méi)有關(guān)閉就在析構(gòu)函數(shù)中自己關(guān)閉它。這樣可以防止連接被泄漏。如果在 DBConnection 的析構(gòu)函數(shù)中調(diào)用 close 失敗,無(wú)論如何,我們還可以再返回到終止或者抑制。class DBConn public:.void close() / new function for / client usedb.close();
9、closed = true;DBConn()if (!closed) try / close the connectiondb.close(); / if the client didntcatch (.) / if closing fails,make log entry that call to close failed; / note that and. / terminate or swallowprivate:DBConnection db;bool closed; 將調(diào)用 close 的責(zé)任從 DBConn 的析構(gòu)函數(shù)轉(zhuǎn)移到 DBConn 的客戶
10、(同時(shí)在 DBConn 的析構(gòu)函數(shù)中包含一個(gè)“候補(bǔ)”調(diào)用)可能會(huì)作為一種肆無(wú)忌憚地推卸責(zé)任的做法而刺激你。你甚至可以把它看作一個(gè)忠告(使接口易于正確使用)的違背。實(shí)際上,這都不正確。如果一個(gè)操作可能失敗而拋出一個(gè)異常,而且可能是一個(gè)需要處理的異常,這個(gè)異常就必須來(lái)自非析構(gòu)函數(shù)。這是因?yàn)槲鰳?gòu)函數(shù)引發(fā)異常是危險(xiǎn)的,永遠(yuǎn)都要冒著程序夭折或未定義行為的風(fēng)險(xiǎn)。在此例中,讓客戶調(diào)用 close 并不是強(qiáng)加給他們的負(fù)擔(dān),而是給他們一個(gè)時(shí)機(jī)去應(yīng)付錯(cuò)誤,否則他們將沒(méi)有機(jī)會(huì)做出回應(yīng)。如果他們找不到可用到機(jī)會(huì)(或許因?yàn)樗麄兿嘈挪粫?huì)有錯(cuò)誤真的發(fā)生),他們可能忽略它,依靠 DBConn 的析構(gòu)函數(shù)為他們調(diào)用 close。如果一個(gè)錯(cuò)誤恰恰發(fā)生在那時(shí)如果由 close 拋出如果 DBConn 抑制了那個(gè)異?;蛘呓K止了程序,他們將無(wú)處訴苦。畢竟,他
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 勤工助學(xué)工作總結(jié)15篇
- 酒店實(shí)習(xí)報(bào)告模板錦集10篇
- 愛(ài)話題作文15篇
- 紋身操作手法課程設(shè)計(jì)
- 高中信息技術(shù) 鍵盤和鍵盤操作教案
- DB2301T 193-2024林糧間作技術(shù)規(guī)程
- 動(dòng)脈導(dǎo)管未閉課件
- 借證協(xié)議書(2篇)
- 兒童故事版權(quán)使用合同(2篇)
- 婦幼保健計(jì)劃生育服務(wù)中心傳染病衛(wèi)生應(yīng)急預(yù)案
- 中華人民共和國(guó)史馬工程課件01第一章
- DB63-T 1672-2018+瀝青路面整治工程新舊路面聯(lián)結(jié)層技術(shù)規(guī)范
- 基于CAN通訊的儲(chǔ)能變流器并機(jī)方案及應(yīng)用分析報(bào)告-培訓(xùn)課件
- 園藝療法共課件
- 布氏、韋氏、洛氏硬度換算表
- 鋼筋混凝土地下通道課程設(shè)計(jì)
- 韓流對(duì)中國(guó)文化的影響課件
- 檢驗(yàn)檢測(cè)服務(wù)公司市場(chǎng)營(yíng)銷計(jì)劃
- 醫(yī)務(wù)人員外出進(jìn)修流程圖
- DB32∕T 2349-2013 楊樹(shù)一元立木材積表
- 昌樂(lè)二中271高效課堂培訓(xùn)與評(píng)價(jià)ppt課件
評(píng)論
0/150
提交評(píng)論