C++ 为什么对操作员而言,朋友函数比成员函数更受欢迎<&书信电报;
当您要打印对象时,友元运算符您必须使用自由函数而不是成员函数。对于二进制运算符,左侧始终是C++ 为什么对操作员而言,朋友函数比成员函数更受欢迎<&书信电报;,c++,operator-overloading,C++,Operator Overloading,当您要打印对象时,友元运算符您必须使用自由函数而不是成员函数。对于二进制运算符,左侧始终是*对于成员函数,右侧作为另一个参数传递 对于输出流操作符,左侧始终是流对象,因此,如果要流到标准类,而不是自己编写流,则必须提供一个自由函数,而不是类的成员 虽然可以提供一个向后流操作符作为成员函数,并按如下方式输出: myObject >> std::cout; 正如您所指出的,您不仅会违反非常强大的库约定,而且由于从左到右分组>,所以链接输出操作将不起作用 编辑:正如其他人所指出的,虽然您
*对于成员函数,右侧作为另一个参数传递
对于输出流操作符,左侧始终是流对象,因此,如果要流到标准类,而不是自己编写流,则必须提供一个自由函数,而不是类的成员
虽然可以提供一个向后流操作符作为成员函数,并按如下方式输出:
myObject >> std::cout;
正如您所指出的,您不仅会违反非常强大的库约定,而且由于从左到右分组>
,所以链接输出操作将不起作用
编辑:正如其他人所指出的,虽然您必须使其成为一个自由函数,但如果流媒体功能无法在类的公共界面中实现,则它只需要是一个朋友。您别无选择,它必须是一个自由函数
但是,请注意,它不一定是一个friend
函数。它只需要是一个朋友,如果你真的需要授予它私人访问权。例如,我在编程竞赛中使用以下内容:
template <class A, class B>
std::ostream& operator<<(std::ostream& os, const std::pair<A, B>& p)
{
return os << '(' << p.first << ", " << p.second << ')';
}
模板
std::ostream&operator在您的示例中还有一个原因-它必须是朋友
,因为这是在类定义中定义自由函数的唯一方法。如果您想要一个非好友自由函数,那么它必须在类之外定义
为什么您希望在类中定义它?有时,最好将所有运算符一起定义:
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文件中定义它们
编辑:我使用+=和+作为示例,但没有认真考虑,但您的问题是关于运算符您不能。但是如果你不想让它成为朋友函数,就让它成为一个自由函数,并根据类的公共接口实现它。例如
ostream& operator<<(ostream& os, Myclass& obj)
{
return obj.print(os);
}
ostream& MyClass::print(ostream& os)
{
os << val; // for example.
return os;
}
ostream&operator您真的还需要其他原因吗?@mmyers:我只是尽可能清楚地理解它……它显然不能是成员函数(参见Charles Bailey的答案),但它不一定是朋友-如果您能从类的公共接口实现它,那太好了。你在问题中回答了。它不能是成员函数,因为如果是,您必须编写a
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;
}
ostream& operator<<(ostream& os, Myclass& obj)
{
return obj.print(os);
}
ostream& MyClass::print(ostream& os)
{
os << val; // for example.
return os;
}