我仔细研究了有关朋友功能及其使用的信息。他们能够在不违反 OOP 的黄金法则之一的情况下访问类中的封装数据。在为重载 I/O 操作符(一种基本操作,是学习 C++ 中第一次教授的操作之一)提供各种源代码时,每个人都将操作符定义为在课堂之外实现它的朋友。我的问题是:需要这样做吗?为什么不将函数声明为类的公共成员并从类中插入/显示数据,同时保持所有内容都被封装?这似乎与重载其他运算符没有什么不同,但它被认为是重载 I/O 运算符的传统方法。
谢谢你的时间。
我仔细研究了有关朋友功能及其使用的信息。他们能够在不违反 OOP 的黄金法则之一的情况下访问类中的封装数据。在为重载 I/O 操作符(一种基本操作,是学习 C++ 中第一次教授的操作之一)提供各种源代码时,每个人都将操作符定义为在课堂之外实现它的朋友。我的问题是:需要这样做吗?为什么不将函数声明为类的公共成员并从类中插入/显示数据,同时保持所有内容都被封装?这似乎与重载其他运算符没有什么不同,但它被认为是重载 I/O 运算符的传统方法。
谢谢你的时间。
假设你想operator<<
为你的 class重载X
,所以你可以像这样使用它:
X x;
std::cout << x;
请注意,这std::cout
是运算符的第一个操作数。要将其实现为成员函数,它必须是 的成员std::basic_ostream
,即 的类型std::cout
。您不能将成员添加到已定义的类中。这就是为什么我们将其声明为自由函数。
如果你operator<<
作为 的成员重载X
,它将把一个X
对象作为它的第一个操作数,所以你可以像这样使用它:
X x;
x << something;
这显然不是您在处理 I/O 时想要的。
如果您有一个重载运算符,例如:a @ b
作为成员函数实现,则该调用将转换为a.operator@(b);
. 这意味着该函数必须是左操作数类型的类的成员。在 iostream 的情况下,所有操作员都需要成为 iostream 本身的成员。
虽然 iostream 确实提供了一些插入/提取运算符作为成员,但您通常希望能够在不修改 iostream 类本身的情况下添加更多1。为此,您几乎需要将运算符实现为自由函数而不是成员函数。由于您通常仍然希望它能够访问您计划读/写的任何类型的私有部分(插入/提取,如果您愿意),它通常必须是该类的朋友。