朋友功能及其与I / O运算符的关系

时间:2013-04-29 00:23:25

标签: c++ function io overloading friend

我仔细研究了有关朋友功能及其使用的信息。他们能够访问类中的封装数据,同时不会破坏OOP的黄金规则之一。在提供各种源代码以便重载I / O操作符(基本操作,学习C ++中的第一个操作)时,每个人都将操作符定义为朋友,因为它在类之外实现它。我的问题是:这需要吗?为什么不直接将该函数声明为该类的公共成员,并在保持所有封装的同时从该类插入/显示数据?它似乎与重载其他运算符没什么不同,但它是一种传统的重载I / O运算符的方法。

感谢您的时间。

2 个答案:

答案 0 :(得分:2)

假设您要为您的班级operator<<重载X,因此您可以像这样使用它:

X x;
std::cout << x;

请注意std::cout是运算符的第一个操作数。要将其作为成员函数实现,它必须是std::basic_ostream的成员,std::cout的类型。您无法将成员添加到已定义的类中。这就是我们将其声明为免费功能的原因。

如果您将operator<<作为X的成员重载,则会将X对象作为其第一个操作数,因此您可以像这样使用它:

X x;
x << something;

在处理I / O时,这显然不是您想要的。

答案 1 :(得分:0)

如果您有一个重载的运算符,例如:a @ b作为成员函数实现,则该调用将转换为a.operator@(b);。这意味着该函数必须是类的成员,该类是 left 操作数的类型。在iostreams的情况下,所有运营商都需要成为iostream本身的成员。

虽然iostream确实提供了一些插入/提取操作符作为成员,但您通常希望能够添加更多而无需修改iostream类本身 1 。为此,您几乎需要将运算符实现为自由函数而不是成员函数。由于您通常仍希望它能够访问您计划读/写的任何类型的私有部分(如果您愿意,可以插入/提取),它通常必须是该类的朋友。


  1. 这是所谓的开放/封闭原则的一个例子:该类应该对扩展开放,但不能修改。换句话说,您希望在不修改的情况下对其进行扩展。