2013-05-16 76 views
2
class student 
{ 
private: 
    int age; 
public: 
    student(); 
    student(int a) {age = a;} 
    ~student() {}; 
    friend student& operator+ (int left, student& s); 
    friend ostream& operator<< (ostream& o, student& s); 
} 

... 

student& operator + (int left, student& s) 
{ 
    s.age += left; 
    return s; 
} 

ostream& operator<< (ostream& o, student& s) 
{ 
    o << s.age << endl; 
} 


int main (void) 
{ 
    student a (10); 
    cout << 14 + a ; 
    return 0; 
} 

所以我必須從上面的代碼的兩個問題。重載運算符<<和operator +導致錯誤

  1. 你爲什麼要做return s;operator+ (int left, student& s)功能? 既然您已經通過student對象引用了,爲什麼不能將返回類型設置爲void

  2. 看來,當我把endl放在14 + a之後,我發現一個錯誤,我發現一個錯誤並且它不打印。我知道這與'運營商< <'有關,但我不知道它的確切原因,以及如何防止這種情況發生?

+0

'operator +'應該返回'student'而不是隨機修改它的參數。 – chris

+0

*你用'endl'得到了什麼*錯誤? – ecatmur

回答

6

爲什麼你必須做退貨s;在運算符+(int left,學生& s)函數中?

我必須說,你的operator +定義是奇怪的,因爲它改變了右側對象 - 而operator +一般不會,和值返回一個新的對象。

反正operator +一般不會返回void,以便它允許鏈接,如:

14 + (16 + a) 

但同樣,operator +不應該修改右側對象。你可能打算寫一些像operator +=。考慮改變你的operator +的定義。

似乎每當我在14 + a後放置endl時,我都會收到一個錯誤,我收到一個錯誤並且不打印。我知道這與'運營商< <'有關,但我不知道它的確切原因,以及如何防止這種情況發生?

您的程序有未定義的行爲,因爲您的超載operator <<不會返回任何內容。您應該添加一個return語句:

ostream& operator<< (ostream& o, student const& s) 
//          ^^^^^ 
{ 
    o << s.age << endl; 
    return o; 
// ^^^^^^^^^ <== Without this, your program has undefined behavior. 
//    Value-returning functions MUST return a value (with 
//    the only exception of main()) 
} 

此外,如上做,你應該接受參考student對象const,因爲operator <<不會改變其狀態(如果你沒有這樣做,你不能用const對象使用operator <<

+0

感謝您的回覆!我試圖做一個重載操作符+當非對象類型在左邊,只是爲了練習。所以當你做'一個。操作符+ b'(這個代碼沒有在代碼中實現),例如,操作是在對象上執行的?那麼在'14 + a'中我應該說這個操作也是在對象a上執行的? –

+0

添加一個'int'來改變年齡顯然是運算符濫用濫用(除了你的關於運算符'+'修改它的一個參數的評論之外。 –

+2

+1,並且還將'operator <<'中的參數類型改爲'student const& '。 – hmjd

0

爲1),考慮下面的代碼:

student aStudent = anotherStudent + aDifferentStudent; 

在這裏,我們需要兩個參數和返回值。這就是爲什麼你需要返回類的一個實例。您當前的實現不是執行operator +函數的標準方法,因爲它修改了參數。考慮字符串操作+這裏使用:

std::string aString = "Hello" + " " + "World"; 

從右到左「」和「世界」是文字字符串,傳遞給函數,該函數返回「世界」,然後將其與沿通過「操作你好「的函數(因爲你有2次調用operator +方法)最終返回」Hello World「。你的實現不能這樣做,因爲A)函數參數沒有被聲明爲const,並且B)如果它們是,並且它做了一個const-cast來修改,你會試圖修改一個字符串 - 未定義的行爲。

字符串是人們如何期望運算符+超載運行的一個很好的例子,以避免打破最小驚喜的原則。

至於你的< <和endl問題,這在本質上是相似的。你需要返回o實例。

1

關於1,你不必做任何事情。語言 對您對超載 運算符所做的操作沒有限制。另一方面,可維護性和可讀性, 確實要求重載操作符以某種方式運行,例如對應的內置操作符 。因此:

  • 這是沒有意義超載另外一個名爲 student類型,因爲它沒有任何意義添加學生。 (在 另一方面,你student類似乎真的更像一個 抽象StudentAge

  • 加(運營商+)不要麼修改其 參數。幾乎沒有例外。在你的情況(假設 StudentAge,而不僅僅是Student),我可以看到三個 運營商:StudentAge operator+(StudentAge const& lhs, int rhs )StudentAge operator+(int lhs, StudentAge const& rhs), 和高於一切,StudentAge& StudentAge::operator+=(int rhs)。 最後的更改this,並且前兩個應該 可能實施在第三次過載方面。

  • 所有重載的加法運算符都應返回 的東西,因爲這是內置運算符的作用。 operator+返回一個新對象,並且operator+=返回 對thisreturn *this;)的引用。再次,永遠。

其他都是濫用,只會讓讀者感到困惑。

關於你的第二個問題:你聲明 operator<<返回的東西,所以實現它返回 的東西。剛剛落下的是未定義的行爲(即使沒有任何其他下面的內容,也是 )。