類過載賦值操作符一般都是作為成員函式而存在的,那函式應該返回什麼型別呢?參考內建型別的賦值操作,例如
int x,y,z;
x=y=z=15;
賦值行為相當於x=(y=(z=15)),也就是賦值操作應該返回左運算元的引用,因此,為了和內建型別相容,類中過載賦值操作符應該返回左運算元的引用,即*this,如下類a的過載賦值操作函式的宣告,
class a{};
a& a::operator=(const a&);
對於賦值操作,首先應該想到的是怎麼處理自我賦值,當類包含指標型別的資料時尤為重要,如下所示
class mystring;
mystring a("hello");
mystring b("world");
a=a;
我們知道,進行賦值時,首先要釋放左運算元的資源,然後再根據右運算元對左運算元進行賦值,賦值操作函式如下所示
mystring& mystring::operator=(const mystring& rhs)
當執行a=a時,會產生意向不到的後果,我們在函式中先釋放了左運算元的資源,然後訪問右運算元的資源,然後當自我賦值發生時,this==&rhs,也就是說我們先釋放了資源,然後又訪問了已經被釋放的資源的內容,這顯然會引起程式崩潰,所以我們需要進行是否是自我賦值操作的驗證,修改過後的函式如下
mystring& mystring::operator=(const mystring& rhs)
此時,函式雖然處理了自我賦值,但是仍然存在問題,如果new操作失敗了怎麼辦?
我們已經釋放了左運算元的資源,但是在重新分配資源時由於空間不夠等原因失敗了,如果我們繼續對已經釋放了的資源進行訪問,會產生未定義的結果,賦值操作就不具備異常安全性,對於這個問題有兩種解決方案
第一,調整語句順序,先儲存原來的資源,等重新分配資源完成以後再釋放以前的資源
mystring& mystring::operator=(const mystring& rhs)
這段**也能夠處理自我賦值,但是必須執行完函式中的所有複製、分配和釋放操作,如果自我賦值發生的概率比較高,我們也可以將測同語句放進該函式。
第二、採用copy and swap技術
mystring& mystring::operator=(const mystring& rhs)
return *this;
}這種技術賦值的是指標而不是為物件重新分配資源,我們在if語句內重新構造了乙個新的臨時物件,然後將臨時物件的str和本類物件的str進行交換,當程式執行到if語句外時,臨時物件自動呼叫析構函式,釋放自己的資源,此時臨時物件所持有的資源就是原來this所持有的資源,該資源得以釋放,而現在this所持有的資源是rhs所持有的資源,即此時rhs和this中的str所指向的是同一塊空間。
對於有繼承關係的類,在對其派生類編寫複製控制的函式時,由於派生類無法訪問基類中的私有成員,所以在派生類的過載操作符函式中,需要首先呼叫其基類的賦值操作符函式對派生類中的基類成員進行賦值,然後再對派生類中的特有成員進行賦值。
C 之 過載賦值操作符
widget 中,有乙個 bitmap 型指標 pb class bitmap class widget 在 widget 類中過載 時,需考慮以下方面 整數 15 首先賦值給 z,得到新值的 z 再賦值給 y,接著得到新值的 y 最後再賦值給 x,如下所示 int x,y,z x y z 15 c...
C 賦值操作符
定義類時,編譯器會自動幫我們定義的有四個 建構函式 析構函式 複製建構函式 賦值操作符。賦值操作符定義了該型別的物件賦值時會發生什麼。過載操作符是一些函式,其名字為operator後跟著所定義的操作符的符號。通過定義名為operator 的函式,我們可以對賦值操作符進行定義。該函式有返回值和形參表。...
C 操作符過載
1.作為成員過載 class myclass public myclass operator const myclass d cons friend myclass operator const myclass a1,const myclass a2 關於返回值型別的討論 呼叫者堆疊裡返回乙個物件效...