C++运算符号重载详解

接下来我们用来举例的代码

class Date{
int year;
int month;
int day;
};

目录

1)=   重载

2)>    重载

3)  >=    重载

4)<   重载

5)<=   重载

6)==   符号

7)+  重载

8)+=   重载

9) <<  流输出重载

10)  >>  输入流重载

总结:


1)=   重载

很多人认为 在不是初始化的时候利用 =  号是拷贝构造函数实现的,其实不然,这个是系统默认的  =  实现的,但它也有弊端,就是浅拷贝(指针等不是重新开辟的空间,而是单纯的拷贝,会导致同一块空间被反复使用和释放),因此想要实现深拷贝就需要我们自己写一个函数的重载。接下来我们先看代码

Date& Date::operator=(const Date& d){ //引用返回值  operator  重载符号  参数
	_year = d._year;
	_month = d._month;       //返回引用是因为要实现 a=b=c
	_day = d._day;           //const是因为这个是拷贝是不会改变d的,这样可以保证数据不被意外改动
	return *this;             //this是指针要解引用才能得到真正的Date
}

现在考虑重载函数的命名,我们要知道函数的重载有两种方式,一个是写在类里面作为成员函数的方法,一个是写在类外实现的,但是有一个要求,就是参数的顺序要对应运算符的参数顺序。=  又是一个特例,因为类里面已经有一个   =   的默认系统实现了,如果我们写在类外,就不能覆盖类内的成员函数,导致程序出现二义性。

里面还有一个细节在括号()里面第一个默认参数是this ,因此符合了参数的顺序关系

2)>    重载

返回值为bool,因为>符号只需要结果,结果只有两种:真和假

这个符号可以用成员函数和在类外实现,因为系统没有默认的<符号重载

成员函数实现:

bool Date::operator>(const Date& d) {
	if (_year > d._year)
		return true;
	if (_year < d._month)
		return false;
	if (_month > d._month)
		return true;
	if (_month < d._month)
		return false;
	if (_day > d._day)
		return true;
	else return false;
}

类外实现

bool operator>(const Date& b,const Date& d) {
	if (b._year > d._year)
		return true;
	if (b._year < d._month)
		return false;
	if (b._month > d._month)
		return true;
	if (b._month < d._month)
		return false;
	if (b._day > d._day)
		return true;
	else return false;
}
3)  >=    重载

返回值为bool,因为>=符号只需要结果,结果只有两种:真和假

类内重载

bool Date::operator >= (const Date& d) {
	if (_year > d._year)
		return true;
	if (_year < d._month)
		return false;
	if (_month > d._month)
		return true;
	if (_month < d._month)
		return false;
	if (_day >= d._day)
		return true;
	else return false;
}

类外实现

bool operator >= (const Date& b,const Date& d) {
	if (b._year > d._year)
		return true;
	if (b._year < d._month)
		return false;
	if (b._month > d._month)
		return true;
	if (b._month < d._month)
		return false;
	if (b._day >= d._day)
		return true;
	else return false;
}
4)<   重载

如果使用上面相同的方法我们不免太无趣,我们这里使用一个偷懒的方法———复用

bool Date::operator < (const Date& d) {
	if (*this >= d)
		return false;
	return true;
}

类外也同样复用即可

5)<=   重载
bool Date::operator <= (const Date& d) {
	if (*this > d)
		return false;
	return true;
}
6)==   符号

这个返回值同样为bool,因为结果只有真假之分

bool Date::operator==(const Date& d) {
	if (_year == d._year  && _month == d._month && _day == d._day)
		return true;
	return false;
}
7)+  重载

因为要支持   a=a+b=a+c;因此返回值应该为临时拷贝或者引用

Date Date::operator+(int day) {
	Date temp = *this;
	temp._day += day;
	while (temp._day > GetMonthDay(temp._year, temp._month)) {
		temp._day -= GetMonthDay(temp._year, temp._month);
		temp._month++;
		if (temp._month > 12) {
			temp._year++;
			temp._month -= 12;
		}
	}
	return temp;
}
8)+=   重载

因为要支持   a=a+b=a+c;因此返回值应该为引用,不能为临时拷贝,因为无法实现(a+=7)++;

Date& Date::operator+=(int day) {
	*this = *this + day;
	return *this;
}
9) <<  流输出重载

首先我们要知道返回值,我们知道这个是允许连续操作的,例如:cout<<a<<b;因此返回值应该是cout,而cout的返回类型是ostream,我们返回它的引用即可。

重要:因为它的第一个参数是cout,如果使用类内重载,默认第一个参数是类Date,因此无法达到我们想要的效果,我们只能使用类外重载。

ostream& operator<<(ostream& out,Date a){
out<<a._year<<a.month<<a.day<<endl;
return out;
}
10)  >>  输入流重载

首先我们还是考虑返回值,我们可以通过查找文献得知,>>的返回值是支持连续操作的istream类型,因为参数的顺序原因我们还是只能使用类外函数来实现。

istream& operator>>(istream& in,Date a){
in>>a._year>>a.month>>a.day<<endl;
return in;
}
总结:

细节:类内成员函数方式重载的第一个参数是this指针,因为输入输出流的第一个参数是iostream,所有无法用成员函数的方式重载,而赋值符号重载 = 因为系统有一个默认的符号重载,所以无法以全局函数方式重载。其次我们要考虑运算符支持的操作,从而考虑返回类型。

授人以鱼不如授人以渔,我虽然没有列举出来所有的重载,类型,但我将重载如何入手以及需要的注意点和细节全部传授出来了,只要你认真阅读本文章,是能掌握运算符重载的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

非洲下暴雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值