2014-02-21 75 views
2

我是計算機科學的學生。在回答之前請完整閱讀我的問題爲什麼我們在重載分配中使用return * this?

今天在C++類中,我們瞭解了重載操作符,特別是賦值操作符,而我的教授說了一些他不喜歡的內容:「請相信我。他在提及return *this公約時說過這句話。

我問,「但是爲什麼?」他的回答很多,「因爲它是。」

我對這個答案不滿意。

考慮以下幾點:

class length 
{ 
private: 
    int inches, feet, yards; 
public: 
    //getters, setters, etc. 
    Length operator=(const Length& Q) 
    { 
     this->inches = Q.inches; 
     this->feet = Q.feet; 
     this->yards = Q.yards; 
     return *this; 
    } 
}; 

基礎上,通過無數的問題和至少3個C++的書認爲,「公約」的存在,因爲它允許擺弄我明白鏈分配爲什麼是必要的以及它是如何成爲?

一個更深入的問題是this如何對班級的屬性(IE this->inches)有單獨的「孩子指針」(我的名詞,不是官方的)?這是如何運作的?是this->inches只是一個偏移或什麼?

我的教授和我真的很感謝一個答案,這不僅僅是「因爲它是如何完成的」。

請和謝謝

編輯:我想我是在寫這個問題明確;但是,根據我收到的答覆,我認爲存在一個錯誤的交流。我試圖理解公約的來源(我相信C的根源)以及爲什麼它是這樣。

+2

@MartinJ。 - 好的發現,但對其他人投票結束,請看看接受的答案。然後考慮下調它,並提出一個正確的。 –

+4

如果你的教授不能提出比「因爲它是如何完成」更好的答案,你應該找一位新教授。 –

+0

我個人的觀點是,返回一個指針是技術上正確的事情,但這太'C'了。得像那些其他時髦的語言,並試圖隱藏指針的存在。 –

回答

3

既然你是不是滿意的答覆「因爲它是」,讓我給你一個不同:

當重載運營商,如做確實int

該建議的原因是遵循最少驚喜的原則,人們習慣於以特定的方式對現有類型進行查看和行爲。當他們在你的類型中使用操作符時,有一個隱含的期望,即它將表現相同。

現在接下來的問題是爲什麼int這樣表現?爲此,我沒有一個明確的答案。它提供了一些花哨的語法,如:(a = 3) = 5,++(a = 3)(x = y).change(),但尚不清楚在這三種情況下的真實價值。在第一種情況下,您可以直接分配5,在另外兩種情況下,將表達式重寫爲兩個單獨的表達式將使代碼更具可讀性。

我有意避免的a = b = c的情況下,在先前的參數,因爲這種情況下支持這樣的觀點,該操作人員應產生,或者參考,以便它可以在後面的分配中使用,的約定是返回一個可修改的參考,並且上面的表達式不需要這個。 A const &就足以支持上述語法。 [然後呢,這個語法真的需要嗎?將其分解爲兩個陳述的成本是多少?它不會更具可讀性嗎? (在很多情況下可能會更好,在某些情況下可能不會)]。

無論如何課帶回家是遵循原則至少驚訝,和任何的理由,導致這一行爲的所有基本或其它標準類型,一旦它成爲一個成語,最好是剛跟着它。

2

賦值是一個表達式。它同時具有一種效果(將右側的一些數據複製到左側)和一個值。除非你想打破慣例並且發生奇怪的事情,否則這個值就是左邊的東西(即this)。 if (a = b)如果a從作業成爲true,則爲true,並且a = b = cc分配給ab

this answer中所述,最好通過引用而不是按值返回的原因是它避免了不必要的複製。

+0

是的。賦值返回一個值促進簡潔。 – jthill

+0

感興趣:有一些語言(如Python),其中賦值*不是*表達式:它是一種語句,它有副作用,但它沒有值,因爲它不能在*語句中使用*。 – hobbs

+2

從形式上講,'a = b = c'不會將'c'分配給'a'和'b'。它只將'c'分配給'b',然後將'b = c'的結果分配給'a'。 'b = c'的結果可能與'c'本身有很大不同。即使使用內置運算符,也會將'a'分配爲'c',並將其轉換爲'b'類型,該類型本身也不是'c'。例如,在'int a;無符號字符b; a = b = -1;'變量'a'將得到*正值*。 – AnT

3

的共識似乎是,operator=傳統返回*這使結構,如:

a = b = c 

這是C的傳統行爲擴展到類。
順便說一句,你operator=的簽名也許應該是:

Length& operator=(const Length& Q); 

,因爲你不希望創建一個新的臨時對象SA返回值

+0

出於好奇,爲什麼我不想返回TNO(臨時無名對象)?在'operator +(const Length&Q)'中我們肯定會返回一個TNO,所以爲什麼不在這裏分配? –

相關問題