“自我賦值”發生在對象被賦值給自己時:
class Widget { ... }; Widget w; ... w = w; //賦值給自己
operator=,不僅不具備“自我賦值安全性”,也不具備“異常安全性”。
讓operator= 具備“異常安全性”往往自動獲得“自我賦值安全性”的回報。因此越來越多的人對“自我賦值”的處理態度是不去管它,而把焦點放在實現“異常安全性”上。
確保代碼不但“異常安全”而且“自我賦值安全”的一個替代方案是,使用所謂的copy and swap技術。此技術和“異常安全性”有密切關系,它是一個常見而夠好的operator=撰寫辦法,其實現方式為:
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; }
上述實現方式因為:1、某類的copy assignment操作符可能被聲明為“以by value方式接受實參”;2、以by value方式傳遞東西會造成一份復件/副本
此方式犧牲了清晰性,然而將拷貝動作從函數本體移至“函數參數構造階段”卻可令編譯器有時生產更高效的代碼