操作符重载 之 输出操作符"<<"(C++)

版权声明:转载请注明作者和出处。 https://blog.csdn.net/LQMIKU/article/details/79262911

操作符重载 之 输出操作符”<<”(C++)

  • 问题背景
  • 技术推演
  • 解决方案
  • 总结

阅读之前注意:

本文阅读建议用时:30min
本文阅读结构如下表:

项目 下属项目 测试用例数量
问题背景 0
技术推演 2
解决方案 2
总结 0

问题背景

在C++中,我们自己定义了一个类,但我们却不能用cout来直接输出这个自定义类的具体对象。你可以试一试,编译器会报错的,这主要是因为编译器不知道该按照什么方式来输出你自定义的类。
那我们就想用cout来直接输出呢?怎么办呢?哈哈,我们有利器——操作符重载!这样我们就可以规定输出方式,有了规则,编译器看到我们的这个类的对象就知道怎么输出了。

技术推演1

首先我们要承认的是,C++是把操作符重载用函数来实现的2

比如我们要实现下面的自定义类A的对象的加法,该怎么做呢?自然能够想到的,就是用函数来把对象中的每个成员变量做加法,参考以下代码:

#include"iostream"
using namespace std;

class A{
public:
    A(int a = 0, int b = 0)//使用默认参数,这样既是有参构造函数,也是默认构造函数
    {
        this->a = a;
        this->b = b;
    }
public://为了方便起见,设置为public
    int a;
    int b;
};

A addA(A &A1,A &A2)//实现对象加法的函数
{
    A tmp;
    tmp.a = A1.a + A2.a;
    tmp.b = A1.b + A2.b;
    return tmp;
}

void main()
{
    A a1(1, 2), a2(3, 4);
    A a3 = addA(a1, a2);//用函数来做对象的加法
    cout << "a" << a3.a << " b" << a3.b << endl;
    system("pause");
}

接下来我们看看操作符重载是怎么用函数实现的:

#include"iostream"
using namespace std;

class A{
public:
    A(int a = 0, int b = 0)//使用默认参数,这样既是有参构造函数,也是默认构造函数
    {
        this->a = a;
        this->b = b;
    }
public://为了方便起见,设置为public
    int a;
    int b;
};

A operator+(A &A1,A &A2)//操作符重载
{
    A tmp;//这里会调用默认构造函数
    tmp.a = A1.a + A2.a;
    tmp.b = A1.b + A2.b;
    return tmp;
}

void main()
{
    A a1(1, 2), a2(3, 4);
    A a4 = operator+(a1, a2);
    A a5 = a1 + a2;
    cout << "a" << a4.a << " b" << a4.b << endl;
    cout << "a" << a5.a << " b" << a5.b << endl;
    system("pause");
}

上面代码中是用全局函数来实现操作符重载,事实上这并不是正规写法,但为了方便理解,正不正规姑且不论。在main函数中,我们可以看到语句“A a4 = operator+(a1, a2);”和语句“A a5 = a1 + a2;”的效果都是一样的。
因此我们可以推测,C++编译器在看到自定义类型在做加法时,也就是看到+号,它会自动的调用重载函数,把左操作对象(+号左边的对象)和右操作对象(+号右边的对象)分别传入重载函数。这样一来,我们就知道C++确实是把操作符重载用函数来实现的。

解决方案

思路:根据以上的技术推演,我们可以同样的应用在“<<”操作符上,那么这个操作符重载的话,需要什么参数呢?毫无疑问,我们自定义类型的对象的参数需要传进去。
我们先看看以下代码:

#include"iostream"
using namespace std;

void main()
{
    int a = 10;
    char *b = "hello, world";
    cout << a;
    cout << b;
    system("pause");
}

可以看到,基础的类型(也就是int和字符串指针类型)作为了参数,但还有一个参数,看来看去,就只有cout了=-=,哈哈,想不到吧,cout竟然也是一个参数。
其实如果我们右键查看一下cout,就能看到下面图片中的内容
cout
看到了吧,cout前面带着一个类型说明符“ostream”,即cout也是一个类的对象。
这样我们就知道重载”<<”需要哪些参数了:一个是ostream类型的对象,还有一个就是我们自定义类型A的对象。
下面我们就来实现它!
参考以下代码:

#include"iostream"
using namespace std;

class A{
public:
    A(int a = 0, int b = 0)//使用默认参数,这样既是有参构造函数,也是默认构造函数
    {
        this->a = a;
        this->b = b;
    }
public://为了方便起见,设置为public
    int a;
    int b;
};

void operator<<(ostream &out,A &a1)//操作符重载
{
    out << "a" << a1.a << " b" << a1.b << endl;//这里直接用out
}

void main()
{
    A a1(1, 2), a2(3, 4);
    cout<<a1;
    cout<<a2;
    system("pause");
}

总结

事实上以上代码均不是正规写法,正规写法链接将在以后给出。
最后引用王保明先生的一句话来给本文做总结:“结论倍简单的:首先我们要承认一件事,C++中操作符的重载是用函数来实现的”。


  1. 基于王保明先生的技术推演,王老师讲课真的很不错!
  2. 结论基于王保明先生的讲课内容.

猜你喜欢

转载自blog.csdn.net/LQMIKU/article/details/79262911
今日推荐