2010-10-04 213 views
2

嘿,我得到了一些我無法理解的東西,有兩種類型的解決方案用於重載此運算符1包括朋友在方法的開始處,另一個沒有朋友。 我會非常喜歡,如果some1解釋什麼是他們之間的差異優勢/劣勢。 例如超載運營< <類理性:在C++中重載<<運算符

class Rational: 
{ 
    private: int m_t,m_b; 
    ... 
    friend ostream& operator<<(ostream& out,const Rational& r) // option 1 
    { return out << r.m_t << "/" <<r.m_b;} // continue of option 1 

    ostream& operator<<(ostream& out,const Rational& r){return r.print();} // option 2 
    virtual ostream& print(ostream& out) const // continue of option 2 
    { // 
     return out<<m_t << "/" << m_b; 
    } // 
}; 

有人告訴我,第二個選項心不是正確的,如果some1可以糾正我吧,我會多它並欣賞。 在此先感謝。

+0

http://stackoverflow.com/questions/236801/should-operator-be-implemented-as-a-friend-or-as-a-member-function – DumbCoder 2010-10-04 14:48:12

+0

http://stackoverflow.com/問題/ 2458459/why-friend-function-is-preferred-to-member-function-for-operator – DumbCoder 2010-10-04 14:48:33

+0

http://stackoverflow.com/questions/2828280/c-beginner-friend-functions-and-operator-overloading-什麼是適當的/ – sbi 2010-10-04 20:37:24

回答

2

operator<<(對於ostream)需要是一個自由函數(因爲左邊的參數是流,而不是你的類)。

friend關鍵字使它成爲一個免費函數(一個可以訪問私有成員的免費函數)。

但是,如果可以通過公共接口實現此功能,則最好這樣做,只需使用非朋友免費功能即可。

class Rational: 
{ 
    private: int m_t,m_b; 
    public: 
    ... 
    virtual ostream& print(ostream& out) const 
    { 
     return out<<m_t << "/" << m_b; 
    } 
}; 

ostream& operator<<(ostream& out,const Rational& r) 
{ 
    return r.print(out); 
} 
4

簡短的回答:選項#2實際上不是一個選項,而是一個語法錯誤,因爲它試圖將一個二元運算符定義爲傳遞兩個操作數的成員。

稍微長一點的答案:如果你使第二個操作數成爲一個自由函數(不是類的成員),這將起作用。哪一個更好取決於具體情況和您的偏好。對於初學者來說:第一個缺點是,它允許operator<<訪問Rational(包括私有助手函數)中的所有內容,而第二個的缺點是您可以爲類的公共API引入一個沒有人需要的函數。

+0

有沒有辦法糾正它,所以它會工作? – 2010-10-04 14:30:26

+0

從我聽說的關於C++中的朋友中得到它的缺點 – 2010-10-04 14:31:28

+0

,並且第一個選項是否適用於多態嗎? – 2010-10-04 14:34:37

0

考慮一個函數,應該輸出的Rational的NUM和書房:

ostream& operator<<(ostream& out, const Rational& r) 
{ 
    return out; 
} 

不幸的是,這僅僅是一個全球性的功能。像其他全局功能一樣,它不能訪問Rational的私有成員。爲了使其與Rational對象的工作,你需要使它的Rationalfriend

class Rational 
{ 
    private: int m_t,m_b; 

    // ... 

    friend ostream& operator<<(ostream& out, const Rational& r); 
}; 

ostream& operator<<(ostream& out, const Rational& r) 
{ 
    out << r.m_t << "/" <<r.m_b; 
    return out; 
} 

friend ostream& operator<<(ostream& out, const Rational& r);Rational類指示ostream& operator<<(ostream& out, const Rational& r)功能,可以直接使用Rational的私有成員。

現在,當你寫:

Rational r(1, 2); // Say, it sets num and den 
cout << r; 

下面的函數調用時:

operator<<(cout, r); 

你會寫operator<<作爲Rational一個成員函數?這是不可能的,因爲上述轉換cout必須是第一個參數。如果您operator<<作爲Rational成員:

class Rational 
{ 
    private: int m_t,m_b; 

    // ... 

    public: 

    ostream& operator<<(ostream& out) const 
    { 
     out << r.m_t << "/" <<r.m_b; 
     return out; 
    } 
}; 

你需要調用它是這樣的:

Rational r(1, 2); 
r.operator<<(cout); 

這是醜陋的。