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

操作符重载 之 输出操作符"<<"(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. 结论基于王保明先生的讲课内容. ↩︎

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值