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

2021-09-23 18:08:51 字數 1369 閱讀 1327

「自我賦值」發生在物件被賦值給自己時:

//方式1

class widget;

widget w;

...w = w;

//方式2

a[i] = a[j]; //潛在的自我賦值,如果i和j有相同的值

//方式3

*px = *py; //潛在的自我賦值,若px和py指向同乙個東西

class base;

class derived: public base;

void dosomething(const base& rb,derived* pb); //rb和*pb有可能是同乙個物件

對於運用物件來管理資源,在賦值操作符的情況下就要考慮自我賦值的情況:

class bitmap;

class widget

;//下面operator=實現**,看起來合理,但是不具備異常安全

widget& widget::operator=(const widget& rhs)

要阻止這種錯誤,傳統的方法是operator=最前面乙個「證同測試(identity test)」達到「自我賦值」的校驗目的:

widget& widget::operator=(const widget& rhs)

雖然也不具備「異常安全性」,如果「new bitmap」導致異常,widget最終會導致有乙個指向一塊被刪除的bitmap,這樣的指向有害的,你無法安全刪除它。

一般讓operator=具備「異常安全性」往往自動獲得「自我賦值安全」的回報,如下**,就具備異常安全性,雖然不是處理「自我賦值」的最高效的方法:

widget& widget::operator=(const widget& rhs)

如果關心效率的問題,在operator=函式內手工安排語句的乙個替代方法是:所謂的copy and swap技術,看起來如下:

class widget

;widget& widget::operator=(const widget& rhs)

這個主題的另乙個變奏曲利用一下的事實:1,某class的copy assignment操作符可能被宣告為by value方式傳參;2,以by value方式傳參會造成乙份副本:

widget& widget::operator=(const widget rhs) //此時是rhs的副本

但這種做法很巧妙,但是卻犧牲了清晰性。

確保任何函式如果操作乙個以上的物件,而其中多個物件是同乙個物件時,其行為仍然正確。

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

結論1 確保當物件自我賦值時operator 有良好行為,其中技術包括比較 物件 和 目標物件 的位址 證同測試 精心周到的語句順序 以及copy and swap。例如 class bitmap class widget 證同測試 widget widget operator const widg...

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

一 有別名的存在,所以有可能自我賦值。下面的 不具備自我賦值的安全性 也不具備 異常安全性 class bitmap class widget widget widget operator const widget rhs 自我賦值的話,呼叫的物件和傳入的引數是同乙個物件,this 跟rhs是同乙個...

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

自行管理資源時,可能在停止使用資源之前意外釋放了它。class data class widget widget widget operator const widget rw operator 函式內的 this和rw可能是同一物件,結果就是widget物件持有乙個指標指向一塊已被刪除的data。...