異常安全之Copy and Swap(GeekBand第三周筆記)

上一周課程提到,在拷貝賦值中,需要檢測(cè)自我賦值,一來是提高自我賦值時(shí)的效率,二來避免自我賦值中帶有指針時(shí),因?yàn)閮?nèi)存的釋放導(dǎo)致的其它異常。當(dāng)時(shí)有一個(gè)疑問,

自我賦值在實(shí)際代碼編寫中,并不常見,這樣的檢測(cè),多了一層 if 語(yǔ)句判斷,對(duì)于不是自我賦值的調(diào)用,豈不是降低了效率?

很快,第二周的作業(yè)中,又遇到新的問題。

圖片上是自己寫的cp op= 的實(shí)現(xiàn)。嗯,這里按照之前的學(xué)習(xí),做了自我賦值的檢測(cè),但是,比對(duì)老師給出的評(píng)分標(biāo)準(zhǔn),仍然踩到坑了,忘了判斷other中的_leftup(Point*類型)指針是否為空。

很顯然,這里的判斷也是有必要的??赃昕赃甑闹貥?gòu)了自己的代碼:

改過之后,似乎也不怕other._leftup== nullptr了。

可是,這才一個(gè)指針,就需要這樣一堆的 if 做判斷,如果Rectangle里邊的指針再多一點(diǎn),一個(gè)一個(gè)的判斷下來,這效率該多底?。?!

有沒有什么更好的辦法呢?一頭霧水。

說來也巧,翻閱《Effective C++》的時(shí)候,第29條,

Strive for exception-safe code.

書中提到,異常安全函數(shù)(Exception-safe functions)提供三種保證,基本承諾,強(qiáng)烈保證,不拋擲保證(non-throwing)。這里就不具體展開了。同時(shí),書中還提到,有一個(gè)copy and swap設(shè)計(jì)策略,可以提供“強(qiáng)烈保證”。這個(gè),就是這篇文章的重點(diǎn)了。

所謂copy and swap策略,就是從需要修改的對(duì)象拷貝(copy)一份,對(duì)這個(gè)副本進(jìn)行修改,如果有任何異常,原對(duì)象不會(huì)有改變狀態(tài),如果修改成功,就把修改過的副本和原對(duì)象做一個(gè)置換(swap)。

按照這個(gè)策略,繼續(xù)重構(gòu):

上面兩張截圖,保留了重構(gòu)前后的代碼。operator=的實(shí)現(xiàn),只需要短短兩行代碼,other成員的判斷,自我賦值的判斷,通通不需要了。

這下,之前疑惑的幾個(gè)問題,自我賦值判斷的效率問題,代碼冗余,都得到了很好的解決。那么,為什么可以這樣呢?

這里其實(shí)有一個(gè)很重要的細(xì)節(jié),參數(shù)不是pass by reference,而是pass by value。

我們應(yīng)該知道,當(dāng)初老師講到,參數(shù)盡量pass by reference,因?yàn)椴恍枰獎(jiǎng)?chuàng)建一個(gè)副本。也就是說,by value的時(shí)候,會(huì)提供一個(gè)副本。也就是說,一旦進(jìn)入函數(shù)體,實(shí)際上我們已經(jīng)調(diào)用拷貝構(gòu)造,完成了一個(gè)到other副本的拷貝,這就提供了強(qiáng)烈的異常安全保證:如果拷貝失敗,我們不會(huì)進(jìn)入到函數(shù)體內(nèi),那么this指針?biāo)赶虻膬?nèi)容也不會(huì)被改變。

進(jìn)入函數(shù)體以后,other和this進(jìn)行交換,this的數(shù)據(jù)放到臨時(shí)對(duì)象里,這樣在函數(shù)退出時(shí),舊的數(shù)據(jù)自動(dòng)被釋放。


PS.以前只聽說c++很難,現(xiàn)在發(fā)現(xiàn)一個(gè)難點(diǎn)所在了,各種各樣的原則,策略,有些居然是互相矛盾的。在具體應(yīng)用時(shí),我們有更多的選擇,但如何選擇更合適的呢?這才是真正的難點(diǎn)所在。



本人其它筆記:

拷貝賦值中對(duì)自我賦值的檢查(GeekBand第二周)


優(yōu)雅的使用inline

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. 讓自己習(xí)慣C++ 條款01:視C++為一個(gè)語(yǔ)言聯(lián)邦 為了更好的理解C++,我們將C++分解為四個(gè)主要次語(yǔ)言:...
    Mr希靈閱讀 3,002評(píng)論 0 13
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,698評(píng)論 1 51
  • 史上最全的iOS面試題及答案 iOS面試小貼士———————————————回答好下面的足夠了----------...
    Style_偉閱讀 2,580評(píng)論 0 35
  • 一、溫故而知新 1. 內(nèi)存不夠怎么辦 內(nèi)存簡(jiǎn)單分配策略的問題地址空間不隔離內(nèi)存使用效率低程序運(yùn)行的地址不確定 關(guān)于...
    SeanCST閱讀 8,152評(píng)論 0 27
  • 你說你愿意等待 等待一個(gè)不可預(yù)知的結(jié)果 你說等待也是一種幸福 于是被動(dòng)的你也變主動(dòng) 你說你不知放棄為何物 繼續(xù)明著...
    誰(shuí)還不是仙女咋滴閱讀 207評(píng)論 0 0

友情鏈接更多精彩內(nèi)容