当您打算打印对象时,友方操作员<<用来。我们可以为运算符使用成员函数<< ?
class A {
public:
void operator<<(ostream& i) { i<<"Member function";}
friend ostream& operator<<(ostream& i, A& a) { i<<"operator<<"; return i;}
};
int main () {
A a;
A b;
A c;
cout<<a<<b<<c<<endl;
a<<cout;
return 0;
}
有一点是朋友功能使我们可以像这样使用它
cout<<a<<b<<c
还有其他什么原因?
答案 0 :(得分:11)
对于二元运算符,您必须使用自由函数而不是成员函数,对于成员函数,左侧始终为*this
,右侧作为另一个参数传递。
对于输出流操作符,左侧始终是流对象,因此如果您要流式传输到标准类而不是自己编写流,则必须提供自由函数而不是类的成员。
尽管可以将后向流操作符作为成员函数提供,然后像这样流出:
myObject >> std::cout;
你不仅违反了一个非常强大的库约定,正如你所指出的那样,由于>>
的从左到右的分组,链接输出操作将不起作用。
编辑:正如其他人所说,虽然您必须将其设为免费功能,但如果无法根据班级实施流媒体功能,则只需friend
即可公共接口。
答案 1 :(得分:10)
你别无选择 - 它必须是一个免费的功能。
但请注意,它不一定是friend
函数。如果您确实需要授予私人访问权限,则只需要成为朋友。例如,我在编程比赛中使用以下内容:
template <class A, class B>
std::ostream& operator<<(std::ostream& os, const std::pair<A, B>& p)
{
return os << '(' << p.first << ", " << p.second << ')';
}
无需成为好友,因为first
和second
可以公开访问。
答案 2 :(得分:1)
您的示例中的另一个原因 - 它必须是friend
,因为这是在类定义中定义自由函数的唯一方法。如果你想要一个非朋友自由函数,它必须在类之外定义。
为什么你更喜欢在课堂上定义它?有时将所有操作符定义在一起很好:
struct SomeClass {
// blah blah blah
SomeClass &operator+=(const SomeClass &rhs) {
// do something
}
friend SomeClass operator+(SomeClass lhs, const SomeClass &rhs) {
lhs += rhs;
return lhs;
}
// blah blah blah
// several pages later
};
可能比以下用户更友好:
struct SomeClass {
// blah blah blah
SomeClass &operator+=(const SomeClass &rhs) {
// do something
}
// blah blah blah
// several pages later
};
SomeClass operator+(SomeClass lhs, const SomeClass &rhs) {
lhs += rhs;
return lhs;
}
这当然假定您在类定义中定义了相关的成员函数,而不是在那里声明它们并在.cpp文件中定义它们。
编辑:我使用+ =和+作为示例而没有真正考虑它,但您的问题是关于operator<<
,它没有像operator+
这样的任何密切相关的运算符。但如果operator<<
调用与打印相关的一个或多个成员函数,您可能希望在定义它们的位置附近定义它。
答案 3 :(得分:0)
你做不到。但是如果你不希望它成为友方函数,那就把它变成一个自由函数,并根据类的公共接口来实现它。例如。
ostream& operator<<(ostream& os, Myclass& obj)
{
return obj.print(os);
}
ostream& MyClass::print(ostream& os)
{
os << val; // for example.
return os;
}