將運算符重載作爲成員和非成員函數的想法非常混淆。作爲成員函數和非成員函數的運算符函數
當我們將運算符重載爲非成員函數時,我們的實際意思是什麼,以及當我們將運算符重載爲成員函數時,我們的意思是什麼。雖然我知道非會員功能是朋友的功能。
將運算符重載作爲成員和非成員函數的想法非常混淆。作爲成員函數和非成員函數的運算符函數
當我們將運算符重載爲非成員函數時,我們的實際意思是什麼,以及當我們將運算符重載爲成員函數時,我們的意思是什麼。雖然我知道非會員功能是朋友的功能。
如果您將運算符重載爲非成員函數,則需要在參數列表中明確指定要對其進行操作的對象。
如果您將其作爲成員函數重載,則「this」指針將爲您完成部分工作。
請看下面的例子:
class Test {
public:
friend Test operator+(const Test &lhs, const Test &rhs); // Non-member function
Test operator+(const Test &rhs); // Member function
};
兩者的區別在於,非成員函數沒有this
指針編譯器方便地傳遞給你,只要你是在談論一個特定實例一類。
成員函數有一個lhs推斷,因此你只需要提供rhs。
請注意,「朋友」不是必需的,但如果您想訪問Test的私人會員,則需要它。
編譯器可以基於參數計數來消除歧義。如果你想聲明friend Test operator+(const Test &rhs)
,它會抱怨論證不足,因爲+是一個二元運算符。成員函數操作符+的lhs是「this
」。
例如
class Foo {
public:
Foo operator+(Foo) // member variant
// declared inside the function
}; // end of class
Foo operator+(Foo lhs, Foo rhs) // non-member variant
{ // declared outside the class
// could be just a call to the member variant
lhs.operator+(rhs);
// I usually do this when implementing std::stream operators,
// don't remember why just now.
}
非成員不需要添加爲朋友,也可以是,如果它需要訪問內部狀態。 如果我沒有記錯的話,非成員在編譯器上的模板化代碼和名稱空間方面有一些優勢,在非成員變體中的朋友也可以很好地記錄在類之外有一個函數,具體到這個類。它告訴我,如果我改變這個班,我可能不得不查看非成員操作員,以確保我沒有破壞任何東西。
大多數操作員應該定義爲成員。
class MyClass
{
...
public:
const MyClass& operator+=(const MyClass&);
};
位,這是在行爲以下相同:
class MyClass {...};
const MyClass& operator+=(const MyClass&, const MyClass&);
的在第一示例中隱含this
很是類似的第一個參數的第二示例。如果第二個示例需要訪問MyClass
的內部狀態,則需要使用friend
ed。
class MyClass
{
friend const MyClass& operator+=(const MyClass&, const MyClass&);
};
const MyClass& operator+=(const MyClass&, const MyClass&);
原型的例外是operator<<
上std::ostream
。
std::ostream& operator<<(std::ostream&, const MyClass&);
這在邏輯上是MyClass
的一員,但由於參數的順序它必須是兩個類的非會員或std::ostream
成員。由於您無法將成員添加到std::ostream
,因此必須將其定義爲非成員。
'operator +'通常會返回一個新的類型實例,即'T operator +(const T&lhs,const T & rhs);'。如果返回一個引用,它應該引用什麼?另外,'operator +通常以非成員的方式實現,以允許左操作數的隱式轉換(如果將操作符實現爲成員,則這將不被允許)。 –
一個小例子:(我沒試過編譯這個代碼,但我希望它的工作原理)
class MyClass
{
public:
MyClass operator+(const MyClass& other) const; //member operator declaration
friend MyClass operator-(const MyClass& first, const MyClass& second); //non-member operator friend declaration
private:
int _a;
}
//member operator definition
MyClass MyClass::operator+(const MyClass& other) const
{
MyClass result;
result._a = _a + other._a;
return result;
}
//non-member operator definition
MyClass MyClass::operator-(const MyClass& first, const MyClass& second)
{
MyClass result;
result._a = first._a - second._a;
return result;
}
心靈的差異:在成員運營商定義,我不第一_a前後指定什麼「=」 - 假設這個 - > _ a。
只有當您的類的實例是操作符的第一個參數時,纔可以使用成員操作符函數。例如,如果您想要執行類似2 + myClassObject
的操作,則需要覆蓋非成員操作員MyClass MyClass::operator+(int first, const MyClass& second)
(或者您想要的任何返回值)。
還請注意,我只需要我的非會員運營商的友誼聲明有權訪問私人_a
字段。
非會員「運營商」不一定是「朋友」。 – robert
您不必非非會員運營商的朋友,如果您不需要,您不應該這樣做。 – chris
[重載操作符作爲成員函數或非成員(朋友)函數的可能重複?](http://stackoverflow.com/questions/1905439/overload-operators-as-member-function-or-non-member-friend函數) –