鱼C论坛

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

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

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

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

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

x
#include <iostream>
using namespace std;


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

public:

        Person(int a, int b)
        {
                this->m_A = a;
                this->m_B = b;
        }

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

private:
        int m_A;
        int m_B;
};

//全局函数实现左移重载
//ostream对象只能有一个
ostream& operator<<(ostream& out, Person& p) {
        out << "a:" << p.m_A << " b:" << p.m_B;
        return out;
}

void test() {

        Person p1(10, 20);

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

int main() {

        test();

        system("pause");

        return 0;
}
想知道小甲鱼最近在做啥?请访问 -> 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 作为第一个参数传递给重载的左移运算符函数。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

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

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

首先,让我们来看一下原始代码和问题所在的部分:
class Person {    friend ostream& operator<<(ostream& out, Person& p);public:    Person(int a, int b)    {        this->m_A = a;        this->m_B = b;    }private:    int m_A;    int m_B;};ostream& operator<<(ostream& out, Person& p){    out << "a:" << p.m_A << " b:" << p.m_B;    return out;}void test(){    Person p1(10, 20);    cout << p1 << "hello world" << endl;}int main(){    test();    system("pause");    return 0;}
问题出在 operator<< 的定义处。在这里,你将 operator<< 定义为了一个全局函数,而不是 Person 类的成员函数。因此,在调用 operator<< 时,必须使用 cout 作为第一个参数。

在C++中,对于输出流操作符的重载,通常将其定义为类的成员函数。这样可以使得调用方式更加符合直觉,并且能够正确访问对象的私有成员。下面是修改后的代码:
#include <iostream>using namespace std;class Person {    friend ostream& operator<<(ostream& out, const Person& p);public:    Person(int a, int b)    {        this->m_A = a;        this->m_B = b;    }        // 将operator<<定义为成员函数    ostream& operator<<(ostream& out) const    {        out << "a:" << m_A << " b:" << m_B;        return out;    }private:    int m_A;    int m_B;};// 定义全局的operator<<重载函数ostream& operator<<(ostream& out, const Person& p){    return p.operator<<(out); // 调用Person类的operator<<成员函数}void test(){    Person p1(10, 20);    cout << p1 << "hello world" << endl;}int main(){    test();    system("pause");    return 0;}
在修改后的代码中,operator<< 被定义为 Person 类的成员函数。这样,在调用 operator<< 时,可以使用对象本身作为左操作数,而无需将 cout 放在 Person 对象之前。

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

如果回答对你有帮助,请给我一个最佳答案!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

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

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

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

您好,请问这句话怎么理解,为什么全局函数里面,调用 operator<< 时,必须使用 cout 作为第一个参数呢?
想知道小甲鱼最近在做啥?请访问 -> 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在后,就显示没有对应的匹配运算符,这是为什么呢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-16 09:39

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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