「自我賦值」發生在對象被賦值給本身時:安全
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