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

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>
            久久久久天天天天| 国产亚洲人成网站在线观看| 一本色道婷婷久久欧美| 亚洲动漫精品| 亚洲日本aⅴ片在线观看香蕉| 蜜臀久久99精品久久久久久9 | 亚洲一品av免费观看| 亚洲香蕉在线观看| 久久福利电影| 欧美激情精品久久久久久蜜臀| 欧美日韩在线观看视频| 国产视频在线一区二区| 亚洲国产激情| 亚洲欧美中文另类| 欧美成人精品影院| 一本色道久久综合一区| 久久精品日产第一区二区| 欧美成人免费在线观看| 国产精品99免费看 | 亚洲国产欧美一区二区三区丁香婷| 亚洲国产小视频| 午夜在线播放视频欧美| 美女免费视频一区| 91久久精品一区| 欧美一区二区三区婷婷月色 | 亚洲精品久久久蜜桃| 亚洲欧美色婷婷| 欧美美女福利视频| 国产一区在线视频| 亚洲伊人久久综合| 欧美aaa级| 亚洲欧美日韩国产精品| 欧美日韩日韩| 亚洲第一页在线| 久久精品亚洲| 亚洲一区久久久| 欧美日韩视频不卡| 亚洲精品视频在线观看网站 | 艳妇臀荡乳欲伦亚洲一区| 久久精品国产久精国产爱| 一本大道久久a久久综合婷婷| 久久婷婷av| 国产最新精品精品你懂的| 亚洲一区二区三区午夜| 亚洲国产精品视频| 久久久国产91| 激情小说另类小说亚洲欧美 | 亚洲国产精品一区| 久久久久久久高潮| 国产亚洲日本欧美韩国| 亚洲免费在线看| 一本久道久久久| 欧美日韩国产一区二区| 日韩网站免费观看| 亚洲电影免费在线观看| 久久天天躁夜夜躁狠狠躁2022 | 亚洲免费小视频| 亚洲精品午夜精品| 欧美激情一区二区三区蜜桃视频| 亚洲电影在线看| 老鸭窝亚洲一区二区三区| 久久国产精品一区二区三区四区| 国产欧美精品国产国产专区| 亚洲欧美日韩成人| 亚洲在线一区二区| 国产欧美日韩视频在线观看| 午夜精品一区二区三区在线| 亚洲一区免费视频| 国产一区在线观看视频| 久久久久久日产精品| 久久蜜桃香蕉精品一区二区三区| 亚洲高清不卡在线观看| 亚洲国产高清自拍| 欧美激情久久久久| 国产精品天天摸av网| 亚久久调教视频| 午夜欧美大片免费观看| 激情亚洲网站| 亚洲高清免费在线| 欧美性大战久久久久久久| 欧美在线观看视频在线| 久久精品国产欧美激情| 亚洲国产精品va| 一本色道久久88综合亚洲精品ⅰ| 国产精品私房写真福利视频| 老司机aⅴ在线精品导航| 欧美激情精品久久久久久久变态| 亚洲一区二区三区激情| 久久精品人人爽| 一区二区激情| 欧美在线观看一区| 日韩亚洲在线| 欧美尤物一区| 亚洲最新视频在线播放| 欧美在线日韩| 中文日韩欧美| 老牛嫩草一区二区三区日本| 亚洲午夜伦理| 久久伊人精品天天| 午夜精品久久99蜜桃的功能介绍| 可以看av的网站久久看| 午夜精品www| 欧美成人首页| 久久免费精品日本久久中文字幕| 欧美精品国产精品| 免费看的黄色欧美网站| 国产欧美日韩精品在线| 亚洲激情图片小说视频| 韩日成人在线| 亚洲免费在线观看视频| 在线亚洲免费| 欧美精品1区2区3区| 老司机67194精品线观看| 国产精品日韩精品欧美精品| 亚洲精品在线免费| 亚洲国产综合在线| 久久九九全国免费精品观看| 新狼窝色av性久久久久久| 欧美日韩一区二区国产| 亚洲国产综合在线| 亚洲日韩视频| 麻豆精品精华液| 老巨人导航500精品| 国产日本欧美一区二区| 亚洲最新合集| 亚洲特级毛片| 欧美日韩一区三区| 亚洲人成在线影院| 亚洲欧洲在线一区| 免费av成人在线| 欧美激情一区二区三区高清视频 | 中文日韩在线视频| 欧美日韩国产免费| 亚洲肉体裸体xxxx137| 亚洲国产成人av在线| 久久国产精品99国产| 久久嫩草精品久久久久| 久久激情网站| 久久久青草青青国产亚洲免观| 国产伦精品一区二区三区| 亚洲综合99| 久久久久久**毛片大全| 狠狠操狠狠色综合网| 久久精品国产69国产精品亚洲| 久久精品女人的天堂av| 国产亚洲一本大道中文在线| 久久精品91久久久久久再现| 欧美成人a视频| 一区二区免费在线播放| 国产精品美女诱惑| 久久国产精品色婷婷| 欧美福利视频| 一区二区三区精品视频| 国产精品久久二区| 欧美亚洲日本国产| 欧美大香线蕉线伊人久久国产精品| 在线观看中文字幕亚洲| 欧美激情1区| 亚洲香蕉网站| 玖玖国产精品视频| 一本一本久久| 国产在线乱码一区二区三区| 久久中文字幕导航| 在线亚洲一区二区| 美女视频网站黄色亚洲| 日韩视频精品| 国产欧美日韩视频在线观看| 久久亚洲一区二区三区四区| 亚洲精品日本| 久久久久一区二区三区| 日韩亚洲欧美高清| 国产一区二区三区黄视频| 欧美—级在线免费片| 午夜精品久久久| 亚洲国产视频直播| 久久国产精品久久w女人spa| 亚洲国产美国国产综合一区二区| 欧美日精品一区视频| 久久久久久网站| 国产精品99久久久久久www| 欧美aⅴ一区二区三区视频| 午夜精品久久久久久久久久久久| 亚洲国产成人精品久久| 国产视频一区在线| 欧美视频在线观看一区| 免费在线观看一区二区| 欧美一区二区视频97| 一区二区三区|亚洲午夜| 亚洲大片在线| 久久人人97超碰精品888| 亚洲欧美综合网| 夜夜爽夜夜爽精品视频| 亚洲国产欧美在线人成| 国内成人自拍视频| 国产精品久久二区二区| 欧美日韩一区二区三区在线看| 免费亚洲电影在线| 久热re这里精品视频在线6| 欧美影片第一页| 性欧美1819sex性高清|