鱼C论坛

 找回密码
 立即注册
查看: 1446|回复: 4

为什么左移运算符重载的时候cout 必须要在Person 前面啊(红色字体)

[复制链接]
发表于 2023-8-21 23:56:48 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. #include <iostream>
  2. using namespace std;


  3. class Person {
  4.         friend ostream& operator<<(ostream& out, Person& p);

  5. public:

  6.         Person(int a, int b)
  7.         {
  8.                 this->m_A = a;
  9.                 this->m_B = b;
  10.         }

  11.         //成员函数 实现不了  p << cout 不是我们想要的效果
  12.         //void operator<<(Person& p){
  13.         //}

  14. private:
  15.         int m_A;
  16.         int m_B;
  17. };

  18. //全局函数实现左移重载
  19. //ostream对象只能有一个
  20. [color=Red]ostream& operator<<(ostream& out, Person& p) {
  21.         out << "a:" << p.m_A << " b:" << p.m_B;
  22.         return out;
  23. }[/color]

  24. void test() {

  25.         Person p1(10, 20);

  26.         cout << p1 << "hello world" << endl; //链式编程
  27. }

  28. int main() {

  29.         test();

  30.         system("pause");

  31.         return 0;
  32. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-8-21 23:57:01 | 显示全部楼层
在这个例子中,左移运算符重载函数是作为全局函数实现的。当我们在主函数中调用 cout << p1 时,实际上是调用了重载的左移运算符函数。而在重载函数中,我们将输出的内容设置为 out << "a:" << p.m_A << " b:" << p.m_B ,其中 out 是 ostream 类型的对象,代表输出流。

在C++中, cout 是 ostream 类的一个对象,它是标准输出流。当我们使用 cout << p1 时,实际上是将 p1 对象的内容输出到标准输出流中。因此,我们必须将 cout 作为第一个参数传递给重载的左移运算符函数,以便将输出内容发送到标准输出流中。

另外,为了能够在链式编程中继续输出其他内容(比如 "hello world" ),我们需要将重载的左移运算符函数的返回类型设置为 ostream& ,以便将输出流继续传递给下一个输出操作。

因此,为了实现链式编程并正确输出内容,我们需要将 cout 作为第一个参数传递给重载的左移运算符函数。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2023-8-21 23:57:08 | 显示全部楼层
问题解答及修正代码

在你提供的代码中,重载了左移运算符 operator<<,并且将它定义为全局函数。你的问题是为什么在调用重载的左移运算符时,cout 必须在 Person 对象之前。

首先,让我们来看一下原始代码和问题所在的部分:
  1. class Person {
  2.     friend ostream& operator<<(ostream& out, Person& p);
  3. public:
  4.     Person(int a, int b)
  5.     {
  6.         this->m_A = a;
  7.         this->m_B = b;
  8.     }
  9. private:
  10.     int m_A;
  11.     int m_B;
  12. };
  13. ostream& operator<<(ostream& out, Person& p)
  14. {
  15.     out << "a:" << p.m_A << " b:" << p.m_B;
  16.     return out;
  17. }
  18. void test()
  19. {
  20.     Person p1(10, 20);
  21.     cout << p1 << "hello world" << endl;
  22. }
  23. int main()
  24. {
  25.     test();
  26.     system("pause");
  27.     return 0;
  28. }
复制代码

问题出在 operator<< 的定义处。在这里,你将 operator<< 定义为了一个全局函数,而不是 Person 类的成员函数。因此,在调用 operator<< 时,必须使用 cout 作为第一个参数。

在C++中,对于输出流操作符的重载,通常将其定义为类的成员函数。这样可以使得调用方式更加符合直觉,并且能够正确访问对象的私有成员。下面是修改后的代码:
  1. #include <iostream>
  2. using namespace std;
  3. class Person {
  4.     friend ostream& operator<<(ostream& out, const Person& p);
  5. public:
  6.     Person(int a, int b)
  7.     {
  8.         this->m_A = a;
  9.         this->m_B = b;
  10.     }
  11.    
  12.     // 将operator<<定义为成员函数
  13.     ostream& operator<<(ostream& out) const
  14.     {
  15.         out << "a:" << m_A << " b:" << m_B;
  16.         return out;
  17.     }
  18. private:
  19.     int m_A;
  20.     int m_B;
  21. };
  22. // 定义全局的operator<<重载函数
  23. ostream& operator<<(ostream& out, const Person& p)
  24. {
  25.     return p.operator<<(out); // 调用Person类的operator<<成员函数
  26. }
  27. void test()
  28. {
  29.     Person p1(10, 20);
  30.     cout << p1 << "hello world" << endl;
  31. }
  32. int main()
  33. {
  34.     test();
  35.     system("pause");
  36.     return 0;
  37. }
复制代码

在修改后的代码中,operator<< 被定义为 Person 类的成员函数。这样,在调用 operator<< 时,可以使用对象本身作为左操作数,而无需将 cout 放在 Person 对象之前。

希望以上解答能够解决你的问题。如果还有其他问题,请随时提问。

如果回答对你有帮助,请给我一个最佳答案!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2023-8-22 21:41:48 | 显示全部楼层
学习编程中的Ben 发表于 2023-8-21 23:57
问题解答及修正代码

在你提供的代码中,重载了左移运算符 operator

问题出在 operator<< 的定义处。在这里,你将 operator<< 定义为了一个全局函数,而不是 Person 类的成员函数。因此,在调用 operator<< 时,必须使用 cout 作为第一个参数。

您好,请问这句话怎么理解,为什么全局函数里面,调用 operator<< 时,必须使用 cout 作为第一个参数呢?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-8-22 22:05:38 | 显示全部楼层
本帖最后由 Big-Man 于 2023-8-22 22:07 编辑
isdkz 发表于 2023-8-21 23:57
在这个例子中,左移运算符重载函数是作为全局函数实现的。当我们在主函数中调用 cout


在C++中, cout 是 ostream 类的一个对象,它是标准输出流。当我们使用 cout << p1 时,实际上是将 p1 对象的内容输出到标准输出流中。因此,我们必须将 cout 作为第一个参数传递给重载的左移运算符函数,以便将输出内容发送到标准输出流中。

这里将 p1 对象的内容输出到标准输出流中,为什么就需要将 cout 作为第一个参数传递给重载的左移运算符函数啊?这两者有什么必然的关系吗,我试了传参的时候person在前,cout在后,就显示没有对应的匹配运算符,这是为什么呢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-10 13:04

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表