2013-10-07 48 views
1

我讀Effective c++和整個這個傳來:運算符使用非成員函數重載?

class Rational { ... }; 
const Rational operator*(const Rational& lhs, const Rational& rhs); 

是這個操作符重載?如果是,爲什麼它是奇怪的形式?

在此先感謝。

+2

有什麼不可思議的呢? – aaronman

+1

@aaronman它不應該是'Rational :: operator'來表示類嗎? – khajvah

+0

這不只是不奇怪,它實際上被許多人認爲是很好的風格。 –

回答

2

是這個操作符重載?如果是,爲什麼它是奇怪的形式?

是。該表格不是「怪異」的。這只是允許你將兩個有理數相乘在一起的一種形式。

操作符可以重載作爲成員函數或非成員函數。使用非成員函數的主要優點(就像這樣)是,你明確表示你沒有訪問Rational類的任何私有狀態,也沒有修改左邊的操作數(由於const)。

僅當您要修改左側操作數(this)或需要訪問類型中的私有變量(要求它成爲類的一部分)時,才需要成員函數版本。否則,訪問私有狀態將要求將其聲明爲朋友函數。

+2

如果函數聲明爲朋友,則該函數可以訪問私有狀態。 –

+0

@DavidHammen True - 已添加回答。 –

+0

謝謝,我可能會改變標題,因爲它可能也會幫助其他人。 – khajvah

1

這是常見的和一個好主意。您通常以其他運營商的角度實施運營商,並儘量避免使用過多的成員功能。你的情況:

class Rational 
{ 
public: 
    // member function for += with access to the internals 
    Rational& operator+=(const Rational& rhs); 
}; 

// free function for + using public copy-ctor and +=, 
// therefore no need to access internals of Rational 
// and hence no need to be a member or friend of Rational! 
Rational operator+(const Rational& lhs, const Rational& rhs) 
{ 
    Rational result(lhs); 
    result += rhs; 
    return result; 
} 

由於第二種方法遵循一個共同的模式,也有庫幫你,例如Boost.Operators或我的df.operators。在這些庫的幫助下,您只需要

class Rational : df::commutative_addable<Rational> 
{ 
public: 
    // member function for += with access to the internals 
    Rational& operator+=(const Rational& rhs); 
}; 

自動爲您生成+。