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;
} //
};
我被告知第二个选项是不正确的,如果某个人可以纠正我的话,我会很喜欢它。 提前谢谢。
答案 0 :(得分:4)
简短回答:选项#2实际上不是一个选项,而是语法错误,因为它试图将二元运算符定义为传递两个操作数的成员。
更长的答案:如果你让第二个操作数成为一个自由函数(不是该类的成员),这将有效。哪一个更好取决于具体情况和您的喜好。对于初学者:第一个的缺点是它允许operator<<
访问Rational
中的所有内容(包括私有帮助函数),而第二个的缺点是你向类'public公开了一个函数没有人需要的API。
答案 1 :(得分: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);
}
答案 2 :(得分:0)
考虑一个应该输出Rational
的num和den的函数:
ostream& operator<<(ostream& out, const Rational& r)
{
return out;
}
不幸的是,这只是一个全球性的功能。与任何其他全局函数一样,它无法访问Rational
的私有成员。要使其与Rational
个对象一起使用,您需要friend
Rational
:
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);
这很难看。