友元函数及其与I/O操作符的关系
Friend functions and their relationship to the I/O Operators
我仔细研究了有关好友功能及其使用的信息。它们能够访问类中封装的数据,同时不会违反OOP的黄金规则之一。在提供各种用于重载I/O操作符(一种基本操作,学习c++时最先教的操作之一)的源代码时,每个人都将操作符定义为友元,并在类外实现它。我的问题是:这个需要来完成吗?为什么不直接将函数声明为类的公共成员,并从类中插入/显示数据,同时保持所有内容的封装?这似乎与重载其他操作符没有什么不同,但它是一种被认为是重载I/O操作符的传统方法。
感谢您的宝贵时间。
假设你想为你的类X
重载operator<<
,那么你可以这样使用它:
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);
。这意味着函数必须是左操作数类型的类的成员。在iostreams的情况下,这将是iostream本身成员所需的所有操作符。
虽然iostreams确实提供了一些插入/提取操作符作为成员,但您通常希望能够在不修改iostream类本身的情况下添加更多1。要做到这一点,您非常需要将操作符实现为自由函数,而不是成员函数。由于您通常仍然希望它能够访问您计划读/写(插入/提取,如果您喜欢)的任何类型的私有部分,因此它通常必须是该类的友元。
- 这是所谓的开/闭原则的一个例子:类应该对扩展开放,但对修改关闭。换句话说,您希望扩展它而不修改它。
- C++GTKMM gui循环依赖关系
- this_thread::sleep_for和计时时钟之间的关系是否由C++11标准指定
- Doxygen - 如何在不生成图形的情况下生成文本调用关系结果
- 我已经建立了递归关系,它找到了两个字符串之间最长的连续公共字符串,我怎么能跳过其中一个字符串中的一个字符
- 在 c++ 中对字符串进行操作的关系运算符无法按预期工作
- 如何记住这种递归关系?
- 如何在头文件中声明类模板(由于循环依赖关系)
- 移动语义和深层/浅层复制之间有什么关系?
- 如何在不知道对应关系的情况下在字符串中搜索字符并将其分配给另一个字符?
- 对在不同二进制文件中创建的对象文件的依赖关系
- #include < conio.h> 和 getch() 方法之间的关系是什么?
- 使用Bazel构建具有不同编译器/链接器选项的C/C++依赖关系
- OpenVINO - 推理库插件 libMKLDNNPlugin.so 无法解析依赖关系
- 模拟测试中类的依赖关系
- 关于记忆后这种递归关系的时间复杂度
- C++模板方法中的循环依赖关系
- 解析正交模块的依赖关系
- 在使用c++类的下标操作符传递的数组中使用关系操作符
- 友元函数及其与I/O操作符的关系
- BOOST_STRONG_TYPEDEF和重载关系操作符