亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

C++箴言:在operator= 中處理自賦值

2019-11-17 05:09:45
字體:
來源:轉載
供稿:網友

  一個對象賦值給自己的時候就發生了一次自賦值:

class Widget { ... };

Widget w;
...

w = w; // assignment to self
  這看起來很愚蠢,但它是合法的,所以應該確信客戶會這樣做。另外,賦值并不總是那么輕易辨別。例如,

a[i] = a[j]; // potential assignment to self
  假如 i 和 j 有同樣的值就是一個自賦值,還有

*px = *py; // potential assignment to self
  假如 px 和 py 碰巧指向同一個東西,這也是一個自賦值。這些很不明顯的自賦值是由別名(有不止一個方法引用一個對象)造成的。通常,當引用或者指針指向相同類型的多個對象時,對這些引用和指針進行操作的代碼需要考慮到那些對象可能是相同的。實際上,假如兩個對象來自同一個繼續體系,甚至不需要公開聲明,它們就是相同類型的,因為一個基類的引用或者指針也能夠引用或者指向派生類類型的對象:

class Base { ... };

class Derived: public Base { ... };

void doSomething(const Base& rb, // rb and *pd might actually be
Derived* pd); // the same object
  假如你遵循 Item 13 和14 的建議,你應該總是使用對象來治理資源,而且你應該確保那些資源治理對象(resource-managing objects)被拷貝時行為良好。假如是這種情況,你的賦值運算符在你沒有考慮自拷貝的時候可能也是自賦值安全(self-assignment-safe)的。但是,假如你試圖自己治理資源,無論如何(假如你寫一個資源治理類(resource-managing class),你當然不得不做),你可能會落入在你使用完一個資源之前就已意外地將它釋放的陷阱。例如,假設你創建了一個類,它持有一個指向動態分配 bitmap 的指針:

class Bitmap { ... };

class Widget {
 ...
 PRivate:
  Bitmap *pb; // ptr to a heap-allocated object
};
  下面是一個 Operator= 的實現,表面上看它是合理的,但假如出現自賦值則是不安全的。(它也不是異常安全(exception-safe)的,但我們要過一會兒才會涉及到它。)

Widget&
Widget::operator=(const Widget& rhs) // unsafe impl. of operator=
{
 delete pb; // stop using current bitmap
 pb = new Bitmap(*rhs.pb); // start using a copy of rhs’s bitmap

 return *this; // see Item 10
}
  這里的自賦值問題在 operator= 的內部,*this(賦值的目標)和 rhs 不能是同一個對象。假如它們是,則那個 delete 不僅會銷毀當前對象的 bitmap,也會銷毀 rhs 的 bitmap。在函數的結尾,Widget——通過自賦值應該沒有變化——發現自己持有一個指向已刪除對象的指針。

  防止這個錯誤的傳統方法是在 operator= 的開始處通過一致性檢測來阻止自賦值:

Widget& Widget::operator=(const Widget& rhs)
{
 if (this == &rhs) return *this; // identity test: if a self-assignment,
 // do nothing
 delete pb;
 pb = new Bitmap(*rhs.pb);

 return *this;
}
  這個也能工作,但是我在前面提及那個先前版本的 operator= 不僅僅是自賦值不安全(self-assignment-unsafe),它也是異常不安全(exception-unsafe)的,而且這個版本還是有異常上的麻煩。具體地說,假如 "new Bitmap" 表達式引發一個異常(可能因為供分配的內存不足或者因為 Bitmap 的拷貝構造函數拋出一個異常),Widget 將以持有一個被刪除的 Bitmap 的指針而告終。這樣的指針是有毒的,你不能安全地刪除它們。你甚至不能安全地讀取它們。你對它們唯一能做的安全的事情就是花費大量的調試精力來斷定它們起因于哪里。

  碰巧的是,使 operator= 異常安全(exception-safe)也同時彌補了它的自賦值安全(self-assignment-safe)。這就導致了更加通用的處理自賦值問題的方法就是忽略它,而將焦點集中于取得異常安全。Item 29 更加深入地探討了異常安全,但是在本 Item 中,已經足夠我們在很多情況下來觀察它,仔細地調整一下語句的順序就可以得到異常安全(exception-safe)(同時也是自賦值安全)的代碼。例如,在這里,我們只要注重直到我們拷貝了 pb 指向的目標之后,才能刪除它:

Widget& Widget::operator=(const Widget& rhs)
{
 Bitmap *pOrig = pb; // remember original pb
 pb = new Bitmap(*rhs.pb); // make pb point to a copy of *pb
 delete pOrig; // delete the original pb

 return *this;
}
  現在,假如 "new Bitmap" 拋出一個異常,pb(以及它所在的 Widget)的遺跡沒有被改變。甚至不需要一致性檢測,代碼也能處理自賦值,因為我們為原先的 bitmap 做了一個拷貝,刪除原先的 bitmap,然后指向我們作成的拷貝。這可能不是處理自賦值的最有效率的做法,但它能夠工作。

  假如你關心效率,你可以在函數開始處加上一致性檢測。在這樣做之前,無論如何,先問一下自己,你認為自賦值發生的頻率有多大,因為檢測并不是免費午餐。他將使代碼(源代碼和目標代碼)有少量增大,而且他將在順序流程中引入一個分支,這兩點會減慢運行速度。例如,指令預讀取(instrUCtion prefetching),高速緩存(caching)和流水線操作(pipelining)的效力都將被降低。

  在 operator= 中另一個可選擇的,確保實現是異常安全和自賦值安全的,手動排序語句的技術被稱為 "copy and swap"。這一技術和異常安全關系密切,所以將在 Item 29 中描述。無論如何,這是一個寫 operator= 的足夠通用的方法,值得一看,這樣一個實現看起來通常就像下面這樣:


class Widget {
 ... 
 void swap(Widget& rhs); // exchange *this’s and rhs’s data;
 ... // see Item 29 for details
};

Widget& Widget::operator=(const Widget& rhs)
{
 Widget temp(rhs); // make a copy of rhs’s data

 swap(temp); // swap *this’s data with the copy’s
 return *this;
}
  在這個主題上的一個變種利用了如下事實:(1)一個類的拷貝賦值運算符可以被聲明為傳值參數;(2)通過傳遞一些東西的值來做出它的拷貝:

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;
}
  對我本人來說,我擔心這個方法會攪亂一些聰明的頭腦,但是通過將拷貝操作從函數體中移到參數的構造中,它有時確實能使編譯器產生更有效率的代碼。

  Things to Remember

  ·當一個對象自賦值的時候,確保 operator= 能行為良好。技巧包括比較源對象和目標對象的地址,關注語句順序,和 copy-and-swap。

  ·假如兩個或更多對象相同,確保任何操作多于一個對象的函數行為正確。 更多文章 更多內容請看C/C++技術專題  數據庫處理專題專題,或

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久激情视频免费观看| 成人做爽爽免费视频| 久久99久国产精品黄毛片入口| 亚洲天堂av高清| 久久综合免费视频| 亚洲精品久久久久中文字幕二区| 91精品久久久久久久久久久久久| 久久久精品电影| 日韩毛片在线观看| 中文字幕在线观看日韩| 日本久久久久久| 欧美大片欧美激情性色a∨久久| 成人妇女免费播放久久久| 亚洲国产三级网| 国产精品久久久久久久久| 国产成人精品国内自产拍免费看| 疯狂做受xxxx欧美肥白少妇| 91国内免费在线视频| 国产日韩在线播放| 日韩精品视频在线播放| 成人国产精品日本在线| 日本中文字幕不卡免费| 久久久国产精品一区| 国产精品久久久久久一区二区| 亚洲国产天堂久久综合| 欧美性猛交xxxx富婆| 亚洲最大福利视频网| 国产精品高潮粉嫩av| 精品日韩美女的视频高清| 国产日韩精品电影| 亚洲a在线观看| 欧美中文在线观看| 久久久久九九九九| 中文字幕欧美视频在线| 一本色道久久综合狠狠躁篇的优点| 成人免费网站在线观看| 日本电影亚洲天堂| 国产精品久久久91| xvideos国产精品| 亚洲日本成人网| 亚洲女人被黑人巨大进入| 日本人成精品视频在线| 中文字幕av一区二区三区谷原希美| 国产精品自产拍在线观看中文| 亚洲网站视频福利| 亚洲成人黄色在线| 欧美日韩国产成人在线| 欧美尤物巨大精品爽| 欧洲永久精品大片ww免费漫画| 国产精品老女人视频| 欧美精品videosex性欧美| 中文字幕一区电影| 亚洲精品短视频| 亚洲综合色av| 国产精品久久久久久五月尺| 久久韩国免费视频| 成人免费福利视频| 国产丝袜一区二区| 992tv在线成人免费观看| 亚洲精品国产欧美| 色噜噜国产精品视频一区二区| 最近免费中文字幕视频2019| 国产精品白丝jk喷水视频一区| 久青草国产97香蕉在线视频| 精品成人av一区| 国产精品av免费在线观看| 欧美自拍视频在线| 精品久久国产精品| 国产在线98福利播放视频| www.日韩系列| 国产欧美日韩专区发布| 日韩毛片中文字幕| 国产又爽又黄的激情精品视频| 精品亚洲男同gayvideo网站| www.久久撸.com| 久久影院中文字幕| 亚洲第一中文字幕| 亚洲黄色在线看| 欧美精品videofree1080p| 久久久精品免费| 欧美激情影音先锋| 日韩亚洲欧美成人| 91精品综合久久久久久五月天| 2019最新中文字幕| 精品国产91乱高清在线观看| 深夜福利91大全| 中文国产亚洲喷潮| 久久国产加勒比精品无码| 精品一区二区三区四区在线| 欧美精品激情在线| 欧美老女人性生活| 国产精品视频一区二区高潮| 91高清视频免费观看| 日本三级韩国三级久久| 亚洲最大av网| 国产精品福利网站| 精品久久香蕉国产线看观看gif| 亚洲精品乱码久久久久久按摩观| 成人免费看黄网站| 97精品国产97久久久久久春色| 日韩日本欧美亚洲| 亚洲第五色综合网| 黑人巨大精品欧美一区二区免费| 日韩hd视频在线观看| 91精品国产综合久久香蕉922| 欧美性受xxxx白人性爽| 亚洲国产日韩欧美在线图片| 亚洲国产精品va在线| 国产精品日韩一区| 久久精品99国产精品酒店日本| 国产香蕉精品视频一区二区三区| 国产99在线|中文| 亚洲第一区在线观看| 欧美另类xxx| 日韩精品在线观看视频| 亚洲视频精品在线| 精品久久久久久中文字幕| 国模极品一区二区三区| 国产精品视频自在线| 亚洲国产天堂久久国产91| 欧美老肥婆性猛交视频| 色老头一区二区三区在线观看| 国产视频亚洲视频| 日韩福利视频在线观看| 国产亚洲免费的视频看| 日韩欧美中文字幕在线播放| 欧美成人自拍视频| 国产精品一区二区女厕厕| 欧美精品亚州精品| 国产成人精品国内自产拍免费看| 欧美性资源免费| 午夜精品一区二区三区av| 国产视频久久久| 国模精品系列视频| 国产不卡一区二区在线播放| 97热在线精品视频在线观看| 亚洲激情小视频| 91精品国产91久久久久久吃药| 久久久伊人日本| 亚洲福利在线播放| 亚洲自拍偷拍网址| 亚洲自拍欧美色图| 日韩av在线免费| 韩国福利视频一区| 91精品国产综合久久香蕉的用户体验| 欧美猛男性生活免费| 亚洲福利视频网站| 亚洲一区二区三区sesese| 亚洲影视中文字幕| 中文字幕亚洲一区二区三区| 久久男人资源视频| 欧美在线视频a| 国产精品激情av在线播放| 国产精品免费久久久久久| 亚洲欧美日韩爽爽影院| 久久综合伊人77777| 欧美极品xxxx| 在线免费看av不卡| 国产精品高潮呻吟视频| 最近日韩中文字幕中文| 久久久国产精品一区| 成人激情av在线| 国产视频久久久| 91青草视频久久|