2011-10-22 55 views
0

我寫夾持三個彩車,X Y Z,一些功能和運算符重載Point類LNK2019錯誤。我以下面的形式對運營商編碼:運算符重載和VS2010

inline Point Point::operator+ (Point point) 
{ 
    return Point(x + point.x, y + point.y, z + point.z); 
} 

inline void Point::operator+= (Point point) 
{ 
    x += point.x; 
    y += point.y; 
    z += point.z; 
} 

這是正確的方式來重載這些運算符嗎?我已經測試過它,但是我已經看到了另一種形式,例如:

inline Point& Point::operator+ (Point& point) 
{ 
    return Point(x + point.x, y + point.y, z + point.z); 
} 

inline Point& Point::operator+= (Point& point) 
{ 
    x += point.x; 
    y += point.y; 
    z += point.z; 
     return *this; 
} 

這兩種形式有什麼區別?

而且我可以用我的運營文件Point.cpp內,但如果我嘗試使用它在Main.cpp的說,我得到解析外部符號LNK2019一個錯誤。奇怪的是,我的功能在定義文件之外工作。我錯過了什麼讓這些操作員在他們定義的文件之外工作?

+0

爲了避免鏈接錯誤,我想你可以儘量不要宣佈他們的內聯。雖然我實際上並不期望這會成爲問題的根源。 –

回答

3

的第一家運營商應該是

inline Point Point::operator+ (const Point &point) const 
{ 
    return Point(x + point.x, y + point.y, z + point.z); 
} 

它不應該返回一個參考,因爲它的除外建立一個新的對象,而不是修改現有的(一般的經驗法則)。 const被添加到函數中,因爲它所調用的點不應該被修改。給點作爲參數的引用添加所以不會有不必要的複製

第二個應該是

inline Point& Point::operator+= (const Point& point) 
{ 
    x += point.x; 
    y += point.y; 
    z += point.z; 
    return *this; 
} 

,因爲它應該修改現有的點,所以它應該返回引用。 const被添加到參數中,因爲它不應該被改變。函數本身不是const的,因爲它應該修改點本身。

你會得到鏈接器錯誤是因爲內嵌的。要麼在頭文件中提供完整的實現,要麼刪除內聯。

+0

並在'operator +'的返回值中添加一個'const'。 –

+0

@EricZ:爲什麼?那麼像'Point result = p1 + p2;'這樣的東西將不起作用 – Dani

+0

錯誤。 '點結果= p1 + p2'是按值複製並且工作。 'const'用於防止'p1 + p2 = result'或調用'p1 + p2'上的非const成員函數。 –

2
inline Point& Point::operator+ (Point& point) 
{ 
    return Point(x + point.x, y + point.y, z + point.z); 
} 

這是錯誤的,它返回對函數返回時不再存在的臨時對象的引用。如果你夠幸運的話,會導致段錯誤。如果你嘗試去做,大多數編譯器會給你一個警告。理想情況下,您可以將此運算符編寫爲免費函數,並根據您的成員operator+=執行。

inline Point& Point::operator+= (Point& point) 
{ 
    x += point.x; 
    y += point.y; 
    z += point.z; 
     return *this; 
} 

這是相當多的首選方式,但你應該考慮的point爲const引用,否則你無法使用的臨時使用。返回引用本身就是允許鏈接操作符。一般來說,如果有疑問,請按照整數進行操作,然後按整數進行操作。

綜上,在「cannonical」的實現是:

inline Point& Point::operator+=(Point const& point) 
{ 
    x += point.x; 
    y += point.y; 
    z += point.z; 
    return *this; 
} 

inline Point const operator+(Point left, Point const& right) 
{ 
    return left += right; 
} 

注意,有operator+是一個免費的功能可以轉換到Point發生在兩個操作數,而不僅僅是正確的。它在operator+=方面方便地實現:左邊的說法是爲了有一個臨時副本,我們可以修改採取的價值,我們通過將合適的參數給它這樣做。由於operator+=返回一個引用,我們使用這種返回來提供將被複製爲函數結果的值。

+0

我更喜歡'operator +'的成員版本,因爲'Point'類似乎沒有轉換構造函數。此外,它應該返回'const Point'以保持內置類型的一致性。 –

+0

@Eric Z:增加了'const'。即使'Point'類沒有轉換構造函數,也總是有另一個類決定向其提供轉換運算符的機會。而且由於它獨立於類本身,並且以類接口的形式表示,所以它更好地解耦它並使其成爲一個自由函數。 –

+0

+1:哦。如果是這樣的話,把它作爲非成員函數是有道理的,因爲'operator +'應該是可交流的。 –