Big-Man 发表于 2023-8-21 23:56:48

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

#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;
}

isdkz 发表于 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 作为第一个参数传递给重载的左移运算符函数。

学习编程中的Ben 发表于 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 对象之前。

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

如果回答对你有帮助,请给我一个最佳答案!{:10_254:}{:10_254:}{:10_254:}

Big-Man 发表于 2023-8-22 21:41:48

学习编程中的Ben 发表于 2023-8-21 23:57
问题解答及修正代码

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

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

您好,请问这句话怎么理解,为什么全局函数里面,调用 operator<< 时,必须使用 cout 作为第一个参数呢?

Big-Man 发表于 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在后,就显示没有对应的匹配运算符,这是为什么呢
页: [1]
查看完整版本: 为什么左移运算符重载的时候cout 必须要在Person 前面啊(红色字体)