2010-10-04 134 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); 

这是丑陋的。