widget 中,有乙個 bitmap 型指標 pb
classbitmap;
class
widget ;
在 widget 類中過載 "=" 時,需考慮以下方面
整數 15 首先賦值給 z,得到新值的 z 再賦值給 y,接著得到新值的 y 最後再賦值給 x,如下所示:
intx, y, z;
x = y = z = 15; //
chain of assignments
相當於
x = (y = (z = 15));
為了實現鏈式賦值,函式的返回值須是乙個例項自身的引用,也即 *this;同理,過載其它的復合賦值運算子 (如 +=, -=, *=, /=),也必須在函式結束前返回 *this
widget& widget::operator=(const widget&rhs)
其次要考慮的是,關於自賦值的情況,雖然顯式的自賦值並不常見,但潛在的隱式自賦值仍需注意
widget w;...w = w; //
explict assignment to self
a[i] = a[j]; //
potential assignment to self
*px = *py; //
potential assignment to self
解決方法是,在函式內加乙個 if 語句,判斷當前例項 (*this) 和傳入的引數 rhs 是不是同乙個例項,也即判斷是不是自賦值的情況
如果是自賦值,則不作任何處理,直接返回 *this;如果不是自賦值,首先釋放例項自身已有記憶體,然後再分配新的記憶體,如下所示:
widget& widget::operator=(cosnt widget&rhs)
上例中,假如在分配記憶體時,因記憶體不足或 bitmap 的拷貝建構函式異常,導致 "new bitmap" 產生異常 (exception),則 pb 指向的是乙個已經被刪除的 bitmap
考慮異常安全,乙個方法是先用 new 分配新內容,再用 delete 釋放如下**的內容,如下所示:當 "new bitmap" 丟擲乙個異常時,pb 指標並不會改變
widget& widget::operator=(cosnt widget&rhs)
如果不考慮效率的問題,那麼即使沒有對自賦值進行判斷的 if 語句,其後面的語句也足以應付自賦值的問題
上例中,因為效率的問題,保留了 if 語句,但實際上,因為自賦值出現的概率很低,所以上述**看似「高效」,其實並不然
最常用的兼顧自賦值和異常安全 (exception safety) 的方法是 「拷貝-交換」 (copy-and-swap),如下所示:
widget& widget::operator=(const widget&rhs)
std::swap 屬於標準演算法,其實現如下:
namespacestd
}
以上有三個拷貝:首先拷貝 a 給 temp,然後拷貝 b 給 a,最後拷貝 temp 給 b
對於 widget 類,實現兩個 widget 物件的值交換,只需互換 bitmap *pb 即可,這稱為 pimpl (pointer to implementation)
首先,定義乙個 swap 公有成員函式,如下:
void widget::swap(widget&other)
然後,模板特例化 std::swap 函式,呼叫上面的 swap 函式,實現指標互換
namespacestd
}
綜上所述,過載賦值操作符,需要考慮鏈式賦值、自賦值和異常安全,頗為繁瑣
乙個簡化方法是,在 widget 類中宣告乙個智慧型指標
classwidget ;
此時,過載 "op=",則只需考慮鏈式賦值
widget& widget::operator=(const widget& rhs) //copy operator=
理論上應該可行,尚未在實際專案中驗證 (留待後續測試...)
1) 過載類賦值操作符,首先考慮鏈式賦值-- 函式返回 *this,其次考慮自賦值和異常安全-- 「拷貝-交換」
2) 考慮寫乙個不拋異常的 swap 函式 (consider support for anon-throwing swap)
3) 被過載的類賦值操作符 "op="必須定義為成員函式,其它的復合賦值操作符 (如 "+=", "-=" 等)應該被定義為成員函式
4) 類中使用智慧型指標,可大大簡化過載賦值操作符 「op=」 的實現
C 過載賦值操作符
類過載賦值操作符一般都是作為成員函式而存在的,那函式應該返回什麼型別呢?參考內建型別的賦值操作,例如 int x,y,z x y z 15 賦值行為相當於x y z 15 也就是賦值操作應該返回左運算元的引用,因此,為了和內建型別相容,類中過載賦值操作符應該返回左運算元的引用,即 this,如下類a...
C 之操作符過載
1.所謂過載,就是賦予其新的意義。函式可以過載,操作符也可以過載。操作符的過載給我們的程式設計帶來了很大的便利,因為操作符只能對基本的資料型別進行操作,而對使用者自定義的類等資料結構型別不支援。因此只能對其操作符進行過載之後,才能更加方便地操作我們自定義的類物件等資料型別。但是值得注意的是並不是c ...
c 之操作符過載
include using namespace std class complex void printcom test add2 test t2 this 函式返回元素 complex operator complex c1 complex operator complex operator in...