一、重載operator=返回類型
下面舉例說明,operator=類似。
針對:ostream & operator <<(ostream & os, const ClassType &object)
二、解決operator=自我賦值問題
在實現operator=時考慮自我賦值是必要的就像 x=y ,我們不知道變量x與y代表的值是否為同一個值(把x和y說成是一個指針更恰當一點)。如下
class bitmap{};
class Widget{
public:
Widget& operator=(const Widget& rhn);
private:
bitmap *pb; //定義一個指針指向對分配的空間
}第一版賦值函數:Widget& Widget::operator=(const Widget& rhs)
{
delete pb;
pb = new bitmap(*rhs.pb);
return this;
}這般函數的pb在使用前清理掉之前的pb指向,在接受一個new出來的新對象,看著很順理成章,但當 this 與函數的參數rhs相等時pb = new bitmap(*rhs.pb);會執行出錯,因為我們已經把*rhs.pb delete了。Widget& Widget::operator=(const Widget& rhs)
{
if(*this == rhs)
return *this;
delete pb;
pb = new bitmap(*rhs.pb)
return *this;
}這個版本的賦值函數基本上是可以接受的,但不見的是安全的,因為當new產生異常時pb依然是個不確定的指針。Widget& Widget::operator=(const Widget& rhn)
{
bitmap *pOrig = pb;
pb = new bitmap(*rhn.pb);
delete pOrig;
return this;
} 這個函數在開始時用pOrig記錄了pb,當new沒有異常時我們在把Pb原來的指向空間釋放掉,從而提高了安全性。class Widget {
void swap(const Widget& rhs);
}
Widget& Widget::operator=(const Widget& rhs)
{
Widget temp(rhs); //防止改變rhs
swap(temp);
return *this;
}當然我們也可以by value 傳遞參數Widget& Widget::operator=(const Widget rhs) //按值傳遞是實參的一個copy
{
swap(temp);
return *this;
}copy and swap技術的缺點是巧妙的運用swap喪失了代碼的清晰性,然而將“copy動作”移動到函數參數的構造階段令編譯器有時生成高效的代碼..
三、operator=重載函數、copy構造函數和構造函數深層復制
很容易理解啦,就是在子類中實現上述函數時,不要忘了調用基類的相應函數來復制、賦值和初始化繼承而來的那部分變量!!