關(guān)于賦值有許多有趣的事情,其中之一就是:你可以把賦值操作連在一起:
int x, y, z;
x = y = z = 15; // 一連串的賦值
另一件有趣的事是:這一賦值工作是自右結(jié)合的,所以上面的賦值鏈可以解析成這樣:
在這里,15首先賦值給z,然后這次賦值的結(jié)果(就是更新過的z的值)將賦給y,然后這次賦值的結(jié)果(就是更新過的y的值)又賦給x。
這種實(shí)現(xiàn)方法的本質(zhì)是:賦值時(shí),返回一個(gè)指向運(yùn)算符左手邊參數(shù)的引用,當(dāng)你為你的類實(shí)現(xiàn)賦值運(yùn)算符時(shí),你應(yīng)該遵循這一慣例:
class Widget {
public:
...
Widget& operator=(const Widget& rhs) // 返回值類型是一個(gè)指向當(dāng)前類的引用,
{
...
return *this; // 返回運(yùn)算符左邊的對(duì)象
}
...
};
這一慣例對(duì)于所有的賦值運(yùn)算符同樣適用,不僅僅是上述的標(biāo)準(zhǔn)形式。于是,我們要這樣書寫:
class Widget {
public:
...
Widget& operator+=(const Widget& rhs)
{ // 這一慣例對(duì)于+=、-=、*=等運(yùn)算符均適用
...
return *this;
}
Widget& operator=(int rhs) // 即使某些時(shí)刻運(yùn)算符的參數(shù)不符合慣例,
{ // 賦值運(yùn)算符仍應(yīng)遵守這一慣例
...
return *this;
}
...
};
這僅僅是一個(gè)慣例,不遵循這一慣例的代碼也能夠得到編譯。然而,所有的內(nèi)建數(shù)據(jù)類型,以及標(biāo)準(zhǔn)庫(kù)中所包括(或者即將包括的,可以參見條目54)的所有類型(比如說,string、vector、complex、tr1::shared_ptr,等等)都遵守這一慣例。當(dāng)你要做一些有悖于該慣例的事情時(shí)先要考慮一下,是否有充分的理由這樣做?否則請(qǐng)遵循慣例。
時(shí)刻牢記
l 讓賦值運(yùn)算符返回一個(gè)指向*this的引用。