亚洲免费乱码视频,日韩 欧美 国产 动漫 一区,97在线观看免费视频播国产,中文字幕亚洲图片

      1. <legend id="ppnor"></legend>

      2. 
        
        <sup id="ppnor"><input id="ppnor"></input></sup>
        <s id="ppnor"></s>

        如何編寫異常安全的C++代碼

        字號(hào):

        關(guān)于C++中異常的爭(zhēng)論何其多也,但往往是一些不合事實(shí)的誤解。異常曾經(jīng)是一個(gè)難以用好的語言特性,幸運(yùn)的是,隨著C++社區(qū)經(jīng)驗(yàn)的積累,今天我們已經(jīng)有足夠的知識(shí)輕松編寫異常安全的代碼了,而且編寫異常安全的代碼一般也不會(huì)對(duì)性能造成影響。 使用異常還是返回錯(cuò)誤碼?這是個(gè)爭(zhēng)論不休的話題。大家一定聽說過這樣的說法:只有在真正異常的時(shí)候,才使用異常。那什么是“真正異常的時(shí)候”?在回答這個(gè)問題以前,讓我們先看一看程序設(shè)計(jì)中的不變式原理。
             對(duì)象就是屬性聚合加方法,如何判定一個(gè)對(duì)象的屬性聚合是不是處于邏輯上正確的狀態(tài)呢?這可以通過一系列的斷言,最后下一個(gè)結(jié)論說:這個(gè)對(duì)象的屬性聚合邏輯上是正確的或者是有問題的。這些斷言就是衡量對(duì)象屬性聚合對(duì)錯(cuò)的不變式。
             我們通常在函數(shù)調(diào)用中,實(shí)施不變式的檢查。不變式分為三類:前條件,后條件和不變式。前條件是指在函數(shù)調(diào)用之前,必須滿足的邏輯條件,后條件是函數(shù)調(diào)用后必須滿足的邏輯條件,不變式則是整個(gè)函數(shù)執(zhí)行中都必須滿足的條件。在我們的討論中,不變式既是前條件又是后條件。前條件是必須滿足的,如果不滿足,那就是程序邏輯錯(cuò)誤,后條件則不一定?,F(xiàn)在,我們可以用不變式來嚴(yán)格定義異常狀況了:滿足前條件,但是無法滿足后條件,即為異常狀況。當(dāng)且僅當(dāng)發(fā)生異常狀況時(shí),才拋出異常。
             關(guān)于何時(shí)拋出異常的回答中,并不排斥返回值報(bào)告錯(cuò)誤,而且這兩者是正交的。然而,從我們經(jīng)驗(yàn)上來說,完全可以在這兩者中加以選擇,這又是為什么呢?事實(shí)上,當(dāng)我們做出這種選擇時(shí),必然意味著接口語意的改變,在不改變接口的情況下,其實(shí)是無法選擇的(試試看,用返回值處理構(gòu)造函數(shù)中的錯(cuò)誤)。通過不變式區(qū)別出正常和異常狀況,還可以更好地提煉接口。
             對(duì)于異常安全的評(píng)定,可分為三個(gè)級(jí)別:基本保證、強(qiáng)保證和不會(huì)失敗。
            基本保證:確保出現(xiàn)異常時(shí)程序(對(duì)象)處于未知但有效的狀態(tài)。所謂有效,即對(duì)象的不變式檢查全部通過。
            強(qiáng)保證:確保操作的事務(wù)性,要么成功,程序處于目標(biāo)狀態(tài),要么不發(fā)生改變。
            不會(huì)失?。簩?duì)于大多數(shù)函數(shù)來說,這是很難保證的。對(duì)于C++程序,至少析構(gòu)函數(shù)、釋放函數(shù)和swap函數(shù)要確保不會(huì)失敗,這是編寫異常安全代碼的基礎(chǔ)。
             首先從異常情況下資源管理的問題開始.很多人可能都這么干過:
             Type* obj = new Type;
             try{ do_something...}
             catch(...){ delete obj; throw;}
             不要這么做!這么做只會(huì)使你的代碼看上去混亂,而且會(huì)降低效率,這也是一直以來異常名聲不大好的原因之一. 請(qǐng)借助于RAII技術(shù)來完成這樣的工作:
             auto_ptr obj_ptr(new Type);
             do_something...
             這樣的代碼簡(jiǎn)潔、安全而且無損于效率。當(dāng)你不關(guān)心或是無法處理異常時(shí),請(qǐng)不要試圖捕獲它。并非使用try...catch才能編寫異常安全的代碼,大部分異常安全的代碼都不需要try...catch。我承認(rèn),現(xiàn)實(shí)世界并非總是如上述的例子那樣簡(jiǎn)單,但是這個(gè)例子確實(shí)可以代表很多異常安全代碼的做法。在這個(gè)例子中,boost::scoped_ptr是auto_ptr一個(gè)更適合的替代品。
             現(xiàn)在來考慮這樣一個(gè)構(gòu)造函數(shù):
             Type() : m_a(new TypeA), m_b(new TypeB){}
             假設(shè)成員變量m_a和m_b是原始的指針類型,并且和Type內(nèi)的申明順序一致。這樣的代碼是不安全的,它存在資源泄漏問題,構(gòu)造函數(shù)的失敗回滾機(jī)制無法應(yīng)對(duì)這樣的問題。如果new TypeB拋出異常,new TypeA返回的資源是得不到釋放機(jī)會(huì)的.曾經(jīng),很多人用這樣的方法避免異常:
             Type() : m_a(NULL), m_b(NULL){
             auto_ptr tmp_a(new TypeA);
             auto_ptr tmp_b(new TypeB);
             m_a = tmp_a.release();
             m_b = tmp_b.release();
             }
            當(dāng)然,這樣的方法確實(shí)是能夠?qū)崿F(xiàn)異常安全的代碼的,而且其中實(shí)現(xiàn)思想將是非常重要的,在如何實(shí)現(xiàn)強(qiáng)保證的異常安全代碼中會(huì)采用這種思想.然而這種做法不夠徹底,至少析構(gòu)函數(shù)還是要手動(dòng)完成的。我們?nèi)匀豢梢越柚鶵AII技術(shù),把這件事做得更為徹底:shared_ptr m_a; shared_ptr m_b;這樣,我們就可以輕而易舉地寫出異常安全的代碼:
             Type() : m_a(new TypeA), m_b(new TypeB){}
            如果你覺得shared_ptr的性能不能滿足要求,可以編寫一個(gè)接口類似scoped_ptr的智能指針類,在析構(gòu)函數(shù)中釋放資源即可。如果類設(shè)計(jì)成不可復(fù)制的,也可以直接用scoped_ptr。強(qiáng)烈建議不要把a(bǔ)uto_ptr作為數(shù)據(jù)成員使用,scoped_ptr雖然名字不大好,但是至少很安全而且不會(huì)導(dǎo)致混亂。