2014-10-05 39 views
-2

我試圖將以下函數轉換爲包含-符號而不是減法函數。但它說函數不可行,並且期望第一個參數有一個左值。在C++中重載operator-()

class fraction 
{ 
    long num; 
    long den; 
} 

我排除了構造函數和其他所有東西。

inline fraction fraction::operator+(fraction &f) 
{ 
    fraction t; 
    t.num = num - f.num; 
    t.den = den - f.den; 
    return t; 
} 
inline const fraction sub(const fraction& f,const fraction& s) 
{ 
    return fraction (getNum(f)*getDen(s)-getDen(f)*getNum(s),getDen(f)*getDen(f)); 
} 
+1

嘗試'內聯分數fraction :: operator +(const fraction&f)const' – 2014-10-05 19:39:46

+1

'operator +'應該表示什麼? – juanchopanza 2014-10-05 19:46:30

+0

你可能想爲運算符添加一個'const',因爲'operator-(分數const&f ...'允許它綁定到右值。 – Niall 2014-10-05 20:48:57

回答

1

Herb Sutter's article教導我們率先實行會員減,賦值運算符,然後實現非成員減法運算符而言吧。

所以,我建議這樣的事情:

class fraction 
{ 
    long num; 
    long den; 

public: 
    fraction& operator-=(const fraction& rhs) 
    { 
     [[Underlying operations]] 
     return *this; 
    } 
}; 

inline fraction operator-(fraction lhs, const fraction& rhs) 
{ 
    lhs -= rhs; 
    return lhs; 
} 

成員減,賦值運算符修改對象本身,然後通過引用作爲公約返回本身。

由於我們需要創建一個新的非成員減法,所以我們需要左值。正如我們剛纔觀察到的那樣,它通過const lvalue引用來獲取rhs。減法實際上是由減法賦值操作符完成的。它按值返回lhs。

不要通過引用返回本地對象。這樣做是未定義的行爲。只有當物體的壽命長於功能時才按參考返回,例如該成員減去分配運算符。

由於您提到了一些涉及左值的問題,我應該提到常量左值引用(const T&)可以同時引用左值和右值,但非常量左值引用(T&)只能引用左值。我建議你在因特網上查找「左值」和「右值」,「左值參考」和「右值參考」,這可能會很複雜。


隨着評論不利於使用傳遞的價值就返回值優化等方面的問題,您也可以考慮const引用採取LHS和複製一個本地副本。

inline fraction operator-(const fraction& lhs, const fraction& rhs) 
{ 
    fraction local_copy = lhs; 
    local_copy -= rhs; 
    return local_copy; 
} 
+0

這是一個很好的建議,除了按值取'lhs'禁止返回值優化,所以你實際上可以製作更多的副本而不是必要的,除此之外,它泄露了實現的細節並使操作符對稱,我會說特別的細節是不好的建議! – juanchopanza 2014-10-06 05:42:12

+0

你能詳細說明所有這些點嗎? – 2014-10-06 08:11:02

+0

通過有效殺死RVO返回一個輸入參數,所以你最終會在RVO應用的情況下得到一個額外的拷貝(並且由於移動一個包含兩個long的類型不會比拷貝它的速度快,所以整體上會失去效率。)其他兩點更具風格,看看Sutter的帖子,我看到一些人對此有所評論,我也寫過關於[在博客中](http://juanchopanzacpp.wordpress.com/2 014/05/11 /想速度 - 不要總是通過價值/)一段時間回來。 – juanchopanza 2014-10-06 08:16:17