2015-01-06 31 views
0

我一直在看一些開源代碼,我看到兩種不同的重載操作符的定義。它們之間的區別是什麼?是否有任何好處?這兩種操作符重載有什麼區別?

例如,一個例子中,我們有一個類:

class foo{ 
public: 
    void SetValue(double input_value) {foo_value = input_value}; 
    double GetValue() {return foo_value;} 
private: 
    double foo_value; 
}; 

然後我有時會看到兩種不同類型/樣式重載加法運算符(例如)

class foo{ 
    const foo operator+(const foo& input_foo); 
}; 

const foo foo::operator+(const foo& input_foo) { 
    foo_value += input_foo.foo_value; 
    return *this; 
} 

另一種類型的的超載我有時看到的是:

class foo{ 
    friend const foo operator+(const foo& input_foo1, const foo& input_foo2); 
}; 

const foo operator+(const foo& input_foo1, const foo& input_foo2); // Defined right after class 

const foo operator+(const foo& input_foo1, const foo& input_foo2) { 
    foo temp_foo; 
    temp_foo.SetValue(input_foo1.GetValue() + input_foo2.GetValue()); 
    return temp_foo; 
} 
+4

您的第一個版本的operator +'是完全錯誤的。 –

+1

[運算符重載]的可能重複(http://stackoverflow.com/questions/4421706/operator-overloading) – nbro

+0

您通常將它們定義爲具有兩個參數的類外方法。一方面,它表明它們不是該類的基本組成部分,但只使用其公共API,另一方面,如果左側不是您的類(但是例如int),它也可以工作。 – dascandy

回答

3

一個重載是成員函數而其他是免費的功能。

您可以使用自由函數來提供混合模式算術。例如: -

foo f; 
2 + f; __1 

__1只有在有自由功能operator+時纔會編譯。會員功能operator+在這種情況下不會做任何事情。

+0

'免費功能'? – nbro

+0

@Rinzler非成員函數。 – 0x499602D2

+0

@ 0x499602D2爲什麼要發明新的名字,如果真名是'friend function',不是? – nbro

0

從外部的角度來看,foo::operator+(const foo&)::operaor+(const foo&, const foo&)在使兩個foo-s之間的符號有意義時使+符號具有完全相同的作用。特別是當第一個參數是*this時,第一個就像第二個參數一樣。

從內部的角度來看,它們可以在foo類中具有不同的功能:::operaor+(const foo&, const foo&)是一個「自由函數」(一個在全局級聲明的函數):它在處理參數時具有對稱性的美以同樣的方式,但不能訪問foo的私有數據成員,除非foo本身不會將其識別爲它自己的firend

foo::operator+(const foo&)作爲成員函數可以自由訪問所有foo成員和數據,但作爲foo的成員不太適合「通用算法」(可能更喜歡函數形式)。

也有關於可能的變種其他一些差別:考慮

foo a; 
foo b; 
int k; 

無論是operator+上面看可以賦予意義a+b,但對於a+kk+a

對於a+k你可以有foo::operator+(int)::operator+(const foo&, int),但K + A,你需要::operator+(int, const foo&),因爲沒有辦法有+int一個meber。

所有這一切說,你聲明和實現看「模糊」(或至少語無倫次):

const foo foo::operator+(const foo& input_foo) { 
    foo_value += input_foo.foo_value; 
    return *this; 
} 

當你寫c = a+b你期望的a值改變?

你做什麼,在這裏,被添加到ba創建a複印件(常量爲什麼?這是一個副本畢竟,你已經改變了a)然後分配給c

運營商+應創建一個新的對象,其值之和

富:: foo的運營商+(常量富& ROP)常量//注簽名,使它連貫與decalration { 富TMP; tmp.foo_value = foo_value + rop.foo_value; return tmp; }

這不是返回類型,但成員函數本身是const,作爲參數,如果通過參考給出,這樣就確保a+b既不ab改變。返回類型只是一個普通的值,你可以讓你的調用者根據需要對待它,因爲它返回到他自己的棧幀。