2011-11-19 72 views
1

這是一個賦值運算符。 &rhs != this令人困惑。我的問題:rhs是消息類型的參考。 &rhs是什麼意思? &做什麼(一個參考的內存地址?)? 另一個問題是關於return *this。因爲我們想要一個類型爲Message的引用,但是*這是一個Message類型的對象,對嗎?我們如何將對象返回給引用?&rhs!= this,比較指針的引用?

Message& Message::operator=(const Message &rhs) 
{ 
    if (&rhs != this) 
    { 
     some functions; 
    } 
    return *this; 
} 
+0

明白爲什麼這個模式是在幾乎所有運營商共同=方法,閱讀Scott Meyer的Effective C++;在第3版中,請參閱項目#10和#11(這些可通過亞馬遜的「Look Inside」機制閱讀)http://www.amazon.com/Effective-Specific-Improve-Programs-Designs/dp/0321334876#reader_0321334876其實,整本書都是推薦閱讀。 – franji1

+0

@ franji1:我不會說這很普通。如果你一直交換,那更好,那麼你通常不需要對每個呼叫者強制自我分配檢查。 –

回答

10

&rhs表示引用參照的對象的地址。

Message a; 
const Message &rhs = a; 

if (&rhs == &a) std::cout << "true" << std::endl; 

這是將打印true

引用不是一個不同的對象;它只是一個指針的語法糖,它指向參考它的同一個對象。所以,當你寫return this,它返回一個指向對象,但如果你寫return *this,它返回無論是複製對象的,或參考對象,根據不同的返回類型。如果返回類型是Message &,那麼您告訴編譯器「不作複製,而是返回相同的對象」。現在的相同的對象不過是一個參考。對象的引用可以隨時進行。例如,請參閱上面的rhs聲明;它是const Message & rhs = a,由於targer類型被稱爲引用類型,因此您正在對象a的引用rhs。這很簡單。

+0

'return * this'呢? '* this'是一個對象。但返回類型是一個消息類型引用'Message&' – ihm

+0

所以基本上,rhs只是a的另一個名稱。 – ihm

+1

@姆:是的。它只是另一個名字。這是一個別名。 – Nawaz

2

引用僅僅是一個別名對象。引用是通過調用函數的請求形成的;它們不是(必然)是對象類型的一部分。這可能你已經很熟悉了,但考慮一下:

void f1(int a) { ++a; } 
void f2(int & a { ++a; } 

int main() 
{ 
    int x = 5; 
    f1(x); 
    f2(x); 
} 

當然你知道兩個函數之間的區別。但請注意,x始終只是int類型的對象。無論是通過引用還是按價值傳遞,都不是x的屬性,而是該函數的屬性。

這同樣適用於返回類型:

int q; 
int g1() { return q; } 
int & g2() { return q; } 

int main() 
{ 
    ++g2(); 
    ++g1(); // error 
} 

再次,q只是一個對象。 return q;是按價值還是按參考返還,不是q的財產,而是該功能的屬性。 g1複製q,而g2返回對實際的q對象的引用(我們可以增加)。在您的例子(的g1返回值不能增加,恰恰是因爲它沒有一個永久的存在,這將是毫無意義的(technially,表達的是一個右值)。)

所以,return *this;返回參考到對象本身。這與this無關,但它與所有函數的返回類型爲Message&有關。

+0

謝謝SB,它有很大幫助 – ihm

+0

您是否暗示'++ g1()'是一個編譯錯誤*,因爲它返回一個右值*?如果是這樣,它是不完全正確的。 – Nawaz

+0

@Nawaz:不,表達式*在這一點是一個右值,並且因爲它是基本類型,它不能遞增,我已經重寫了它。 –

4

除了Nawaz的偉大answer,我想指出的是,你必須要小心參考返回到本地變量在函數返回時,將走出去的範圍。因此,避免返回這樣的參考:

string& foo() 
{ 
    string result = "abc"; 
    return result; 
} 

這將導致以下編譯器警告:

參照本地變量result返回