青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Shuffy

不斷的學習,不斷的思考,才能不斷的進步.Let's do better together!
posts - 102, comments - 43, trackbacks - 0, articles - 19

[轉]http://m.shnenglu.com/tiandejian/archive/2007/04/30/ecpp_11.html
第11條:
operator= 中要考慮到 自賦值問題

當對象對其自身賦值時,就發生了一次“自賦值”:

class Widget { ... };

 

Widget w;

...

w = w;                                   // 自賦值

這樣做看上去沒什么意義,但這是合法的,因此以后我們假設客戶端程序員可能會這樣做。而且,賦值工作本身并不總是那么容易辨認的。比如:

a[i] = a[j];                           // 可能發生自賦值

如果 i j 的值相同,那么這就是一次自賦值。另外

*px = *py;                             // 可能發生自賦值

px py 指向同一處時,上面一行也是一次自賦值。這些自賦值并不是那么一目了然,它們是由別名造成的:可以通過多種方式引用同一個對象。大體上講,用來操作指向同一類型多個對象的引用或指針的代碼都應考慮對象重復的問題。實際上,假如兩個對象來自同一層次,即使它們并未聲明為同一類型,也要考慮重復問題,這是因為一個基類的引用或指針可以引用或指向其派生類的類型的對象。

class Base { ... };

 

class Derived: public Base { ... };

 

void doSomething(const Base& rb,       // rb *pd 可能實際上

                      Derived* pd);        // 是同一個對象

假設你遵循第 13 條和第 14 條中的建議,你將會一直使用對象來管理資源,而且在復制時你將會確保資源管理對象能正確工作。如果上邊的假設成立,你的賦值運算符很可能在處理自賦值時將是安全的,你不需要額外關注它。然而如果你試圖自己來管理資源(顯然你在編寫資源管理類時必須要這樣做),此時你很有可能陷入這個陷阱中:一個對象尚未用完,但是你卻不小心將其釋放了。比如說,你創建了一個類其中放置了一個無類型指針,你用這個指針來動態分配位圖:

class Bitmap { ... };

 

class Widget {

 ...

 

private:

 Bitmap *pb;                          // 指向一個分配在堆上的對象

};

下邊給出 operator= 的一個實現,它在表面看上去很合理,但是如果存在自賦值,它便是不安全的。(它在出現異常時也不安全,稍后我們討論這個問題)

Widget&

Widget::operator=(const Widget& rhs)   // operator= 不安全的實現

{

 delete pb;                           // 停止使用當前的位圖

 pb = new Bitmap(*rhs.pb);            // 開始使用 rhs 位圖的一份拷貝

 return *this;                        // 參見第 10

}

此處的自賦值問題出現在 operator= 的內部, *this (賦值操作的目標)和 rhs 有可能是同一對象。如果它們是, delete 便不僅僅銷毀了當前對象的位圖,同時它也銷毀了 rhs 的位圖。 Widget 的值本不應該在自賦值操作中改變,然而在函數的末尾,它會發現:它們包含的指針指向了一個已經被刪除的對象!

防止這類錯誤發生的傳統方法是:在 operator= 的最頂端通過一致性檢測來監視自賦值:

Widget& Widget::operator=(const Widget& rhs)

{

 if (this == &rhs) return *this;       // 一致性檢測: 如果出現自賦值

                                       // 則什么也不做

 delete pb;

 pb = new Bitmap(*rhs.pb);

 return *this;

}

這樣可以正常工作,但是我曾經說過 operator= 的早期版本不僅僅在賦值時不安全,在發生異常時它也會出現問題。特別地,如果“ new Bitmap ”語句引發了一個異常(有可能是可分配內存耗盡,或者是 Bitmap 的拷貝構造函數拋出了一個異常),最后 Widget 所包含的指針仍將指向一個已被刪除的 Bitmap 。這類指針是有毒的。你無法安全的刪除它們。你甚至沒辦法安全的讀取它們。此時你所做的唯一一件安全的事情也許就是耗費大量的精力去排查 bug 。

還好,在讓 operator= 在遇到異常時能安全執行的同時,它也不會在自賦值時出現問題了。因此,你可以把目光集中在異常的安全問題上,而忽略自賦值的問題。第 29 條中深入討論異常中的安全問題,但是本條中已經可以很清晰地看出:在許多情況下,認真安排一下語句可以使你的代碼在出現異常時是安全的(同時在自賦值時也是安全的)。比方說,現在我們只需要認真考慮:在我們沒有把 pb 對象復制出來以前,千萬不要刪除它:

Widget& Widget::operator=(const Widget& rhs)

{

 Bitmap *pOrig = pb;               // 復制原始的 pb

 pb = new Bitmap(*rhs.pb);         // pb 指向 *pb 的這一副本

 delete pOrig;                     // 刪除原始的 pb

 

 return *this;

}

現在,如果“ new Bitmap ”拋出一個異常, pb (及其所在的 Widget )沒有被改動。即使沒有進行一致性檢測,這段代碼也可以解決自賦值問題,這是因為我們復制出了原始位圖的一個副本,并且刪除了原始副本,然后指向我們復制出的那個副本。這也許不是解決自賦值問題的最高效的途徑,但是這樣做確實有效。

如果你考慮到效率問題,你可以重新在程序最開端添加一致性檢測。然而在做這件事之前,問一下自己,你期望自賦值出現的有多頻繁,因為一致性檢測也有系統開銷。首先這使得代碼(源代碼和對象)變得稍長一些,同時它也會為控制流引入一個分支,這兩點都會降低運行的速度。比如說,指令預讀、捕獲、管線分配等操作的執行效率將會受到影響。

為了使 operator= 的實現對異常和自賦值都保證安全,必須為其手動安排語句,這里還有另一個途徑:使用一個稱為“復制并交換”的技術。這一技術更加貼近異常安全問題,所以我們在第 29 條中討論它。但是它在編寫 operator= 時得到了十分普遍的應用,看一下它實現的方法是十分值得的:

class Widget {

 ...

 void swap(Widget& rhs);              // 交換 *this rhs 中的數據 ;

 ...                                  // 更多細節請參見第 29

};

 

Widget& Widget::operator=(const Widget& rhs)

{

 Widget temp(rhs);                     // rhs 的數據保存副本

 swap(temp);                           // 使用上邊的副本與 *this 交換

 return *this;

}

上述的主題可以進行一下演變,可 以利用以下一些事實: (1) 一個類的拷貝賦值運算符的參數可以通過傳值方式實現; (2) 通過傳值可以傳遞這一參數的一個副本(參見第 20 條):

Widget& Widget::operator=(Widget rhs)   // rhs is a copy of the object

{                                       // passed in — note pass by val

 swap(rhs);                            // swap *this's data with

                                        // the copy's

 return *this;

}

從我個人角度來講,我很擔心這一點,這個手段會將清晰度作為“祭祀品”擺放在靈巧性的“祭壇”上,但是把復制操作從函數體中移出來,放在參數結構中,在一些場合確實能夠編寫出更加高效的代碼。

需要記住的

在一個對象為自己賦值時,要確保 operator= 可以正常地運行。可以使用的技術有:比較源對象和目標對象的地址、謹慎安排語句、以及“復制并交換”。

在兩個或兩個以上的對象完全一樣時,要確保對于這些重復對象的操作可以正常運行。

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美日韩免费一区| 欧美电影免费网站| 韩国av一区二区三区| 国产精品视频九色porn| 国产精品久久久999| 欧美日韩大片| 国产精品av久久久久久麻豆网| 欧美a级在线| 欧美日韩国产不卡| 国产精品毛片a∨一区二区三区|国| 亚洲第一视频网站| 亚洲一区中文字幕在线观看| 亚洲欧美国产不卡| 亚洲精品永久免费精品| 一区二区欧美在线观看| 一本色道久久加勒比88综合| 欧美激情久久久久| 欧美电影免费观看网站| 99视频精品全国免费| 亚洲欧美激情诱惑| 久久精品国产99国产精品| 久久这里只有| 欧美午夜在线视频| 在线视频成人| 午夜精品福利在线| 欧美成人一区二区| 亚洲视频在线视频| 久久五月婷婷丁香社区| 欧美性天天影院| 亚洲成人在线视频播放| 小黄鸭精品aⅴ导航网站入口| 免费亚洲电影| 亚洲午夜性刺激影院| 久久综合伊人| 国产麻豆成人精品| 日韩视频免费观看高清在线视频| 欧美亚洲自偷自偷| 亚洲精品国产精品国自产观看浪潮 | 亚洲一卡二卡三卡四卡五卡| 久久国产88| 日韩视频―中文字幕| 亚洲欧美日韩在线高清直播| 激情av一区二区| 久久久亚洲国产美女国产盗摄| 亚洲国产精品一区制服丝袜| 亚洲综合激情| 亚洲片在线观看| 久久精品动漫| 国产欧美在线视频| 亚洲一区二区三区在线看| 欧美福利精品| 久久精品国产2020观看福利| 国产欧美一区二区精品忘忧草 | 欧美中文日韩| 欧美va天堂在线| 国产精品99久久久久久久女警 | 韩国自拍一区| 亚洲精品影院| 国产亚洲欧美中文| 亚洲欧美日韩区| 99re6热只有精品免费观看| 久久久久久久尹人综合网亚洲| 国产精品欧美激情| 日韩视频在线你懂得| 午夜精品福利一区二区蜜股av| 欧美日韩中文字幕综合视频| 一本色道久久精品| 亚洲精品免费一二三区| 欧美国产精品一区| 99在线热播精品免费| 亚洲国产精品视频一区| 欧美电影免费网站| 一本一本大道香蕉久在线精品| 欧美激情一区二区在线 | 亚洲国产精品va在线看黑人| 久久久久久久综合日本| 亚洲欧美综合v| 黄色一区二区三区| 男人的天堂亚洲| 欧美不卡在线视频| 一区二区欧美在线观看| 亚洲综合另类| 在线免费高清一区二区三区| 亚洲国产黄色片| 欧美午夜免费影院| 久久精品中文| 欧美不卡视频一区发布| 亚洲欧美日韩中文播放| 性欧美xxxx视频在线观看| 欧美自拍丝袜亚洲| 欧美一区二区大片| 亚洲男人av电影| 国产一区在线免费观看| 免费观看在线综合色| 欧美黄色aaaa| 亚洲欧美日韩在线| 久久久久久久成人| 在线视频亚洲| 久久gogo国模裸体人体| 亚洲人成精品久久久久| 中文亚洲欧美| 尤物精品国产第一福利三区| 最新69国产成人精品视频免费| 欧美亚洲不卡| 欧美激情一区二区三区四区 | 亚洲国产精品视频一区| 欧美二区不卡| 国产精品地址| 亚洲成人在线视频网站| 国产精品久久一区二区三区| 免费不卡视频| 国产乱码精品一区二区三区不卡 | 一区二区三区在线视频播放| 宅男噜噜噜66国产日韩在线观看| 黄网站色欧美视频| 老妇喷水一区二区三区| 亚洲欧美亚洲| 亚洲精品一区二区三区在线观看| 一本久道久久久| 亚洲福利久久| 久久本道综合色狠狠五月| 亚洲男人av电影| 欧美日韩福利在线观看| 免费黄网站欧美| 国产亚洲人成网站在线观看| 夜夜夜精品看看| 亚洲欧洲一区二区在线观看| 久久精品国产亚洲aⅴ| 亚洲免费视频观看| 欧美日韩国产在线看| 欧美黄色一区二区| 在线观看成人av电影| 久久激情五月丁香伊人| 久久成人精品视频| 国产日韩精品视频一区| 午夜影院日韩| 久久精品一区蜜桃臀影院| 国产精品美女主播| 亚洲性视频h| 欧美一区二区三区日韩视频| 国产精品视频精品| 校园春色综合网| 久久久天天操| 在线观看不卡| 免费视频一区二区三区在线观看| 久久久久一区二区三区| 国产字幕视频一区二区| 久久精品视频免费观看| 免费成人av在线| 亚洲国产日日夜夜| 欧美精品在线观看播放| av成人免费在线观看| 亚洲一区三区电影在线观看| 国产精品久久午夜夜伦鲁鲁| 午夜久久资源| 美女福利精品视频| 亚洲精品婷婷| 夜夜狂射影院欧美极品| 欧美日韩国产综合一区二区| 一区二区高清视频| 羞羞色国产精品| 国产亚洲午夜| 老牛嫩草一区二区三区日本| 欧美护士18xxxxhd| 一本色道久久综合一区| 国产日韩专区| 蜜桃久久精品乱码一区二区| 99精品国产99久久久久久福利| 性高湖久久久久久久久| 在线不卡免费欧美| 欧美视频在线观看| 欧美一区二区三区免费在线看| 女人天堂亚洲aⅴ在线观看| 99国产精品久久久久久久成人热 | 国产一级一区二区| 欧美成人精品| 亚洲欧洲av一区二区| 免费久久99精品国产自| 亚洲一区二区三区高清不卡| 一本到12不卡视频在线dvd| 欧美怡红院视频| 在线播放日韩专区| 国产精品国产三级国产专区53| 一本久道久久综合婷婷鲸鱼| 欧美精品日韩三级| 99精品免费| 久久综合综合久久综合| 在线亚洲免费| 韩国免费一区| 国产精品www| 欧美福利一区二区| 久久国产精品网站| 9色porny自拍视频一区二区| 免费亚洲一区二区| 欧美在线观看视频一区二区| 日韩午夜高潮| 欧美亚洲第一页| 亚洲国产婷婷| 国产精品亚洲视频| 欧美高清视频在线播放|