條款11:在operator= 中處理「自我賦值」

「自我賦值」發生在對象被賦值給本身時:安全

class Widget
{
	...
};

Widget w;
...
w = w;  //賦值給本身

operator=,不只不具有「自我賦值安全性」,也不具有「異常安全性」。函數

讓operator= 具有「異常安全性」每每自動得到「自我賦值安全性」的回報。所以愈來愈多的人對「自我賦值」的處理態度是不去管它,而把焦點放在實現「異常安全性」上。this

確保代碼不但「異常安全」並且「自我賦值安全」的一個替代方案是,使用所謂的copy and swap技術。此技術和「異常安全性」有密切關係,它是一個常見而夠好的operator=撰寫辦法,其實現方式爲:spa

class Widget
{
public:
    ... void swap(Widget& rhs); //交換*this和任rhs的數據 ... }; Widget& Widget::operator=(const Widget& rhs) { Widget temp(rhs); //爲rhs數據製做一份復件(副本) swap(temp); //將*this數據和上述復件的數據交換 return *this; }

另一種實現方式爲:對象

 Widget& Widget::operator=(Widget rhs)	//rhs是被傳對象的一份復件(副本),注意此處是值傳遞 pass by value
 {
	 swap(rhs);		//將*this數據和復件的數據交換
	 return *this;
 }

上述實現方式由於:一、某類的copy assignment操做符可能被聲明爲「以by value方式接受實參」;二、以by value方式傳遞東西會形成一份復件/副本blog

此方式犧牲了清晰性,然而將拷貝動做從函數本體移至「函數參數構造階段」卻可令編譯器有時生產更高效的代碼get

請牢記:編譯器

  一、確保當前對象自我賦值時operator= 有良好行爲。其中技術包括比較「來源對象」和「目標對象」的地址、精心周到的語句順心、以及copy-and-swap。編譯

  二、肯定任何函數若是操做一個以上的對象,而其中多個對象是同一個對象時,其行爲仍然正確。class

相關文章
相關標籤/搜索