C++为了增强代码的可读性引入了运算符重载,对各种数据进行操作,高效快捷且易懂。
运算符重载是为了使自定义类型像内置类型一样去使用运算符。
一.运算符重载的定义
运算符重载是具有特殊函数名的函数,也具有其返回值类型。
函数名字及其参数列表,其返回值类型and参数列表与普通的函数类似。
函数名为:关键词operator+运算符
函数原型:返回值类型+operator+操作符(参数列表)
下面完整地实现一个时间类Date;(长代码警告!)
#include<iostream>
using namespace std;
//完整实现一个日期类
class Date
{
public:
int GetMonthDay(int year, int month)
{
static int monthDays[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
//是二月而是闰年,四年闰一次百年不闰或者四百年闰一次
if (month == 2 && ((year % 4 != 0 && year % 100 != 0) || year % 400 == 0))
{
return 29;
}
return monthDays[month];
}
Date(int year = 0, int month = 1, int day = 0)
{
if (year >= 0
&& month >= 1 && month <= 12
&& day >= 1 && day <= GetMonthDay(year, month))
{
_year = year;
_month = month;
_day = day;
}
else
{
cout << "非法日期" << endl;
_year = year;
_month = month;
_day = day;
}
}
Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
Date& operator=(const Date& d)//返回值类型Date是为了能连续赋值//d1=d2=d3;使用引用返回减少一次拷贝(this出了函数还在,所以可以使用)
{
if (this != &d)//判断是否自己给自己赋值
{
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this;
}
//内联运算符重载函数
inline bool operator < (const Date& d)//bool operator<(Date* this,const Date& d )
{
if (_year < d._year)
return true;
else if (_year == d._year && _month < d._month)
return true;
else if (_year == d._year && _month == d._month && _day < d._day)
return true;
return false;
}
bool operator==(const Date& d)
{
if (_year == d._year && _month == d._month && _day == d._day)
return true;
else
return false;
}
bool operator<=(const Date& d)
{
return (*this < d) || (*this == d);//复用上面的来实现<=
}
bool operator >(const Date& d)
{
return !(*this <= d);
}
Date operator+(int day)
{
Date ret(*this);
ret._day += day;
while (ret._day > GetMonthDay(ret._year, ret._month))
{
ret._day -= GetMonthDay(ret._year, ret._month);
ret._month++;
if (ret._month == 13)
{
ret._year++;
ret._month = 1;
}
}
return ret;
}
Date& operator+=(int day)
{
_day += day;
while (_day > GetMonthDay(_year, _month))
{
_day -= GetMonthDay(_year, _month);
++_month;
if (_month == 13)
{
++_year;
_month = 1;
}
}
return *this;
}
int operator-(const Date& d)
{
Date ret(*this);
Date temp(d);
int sum=0;
if (ret < temp)
{
cout << "注意日期前后" << endl;
while (!(ret == temp))
{
temp._day--;
if (temp._day == 0)
{
temp._month--;
temp._day = GetMonthDay(temp._year, temp._month);
}
sum++;
}
return sum;
}
else
{
while (!(ret == temp))
{
ret._day--;
if (ret._day == 0)
{
ret._month--;
ret._day = GetMonthDay(ret._year, ret._month);
}
sum++;
}
return sum;
}
}
Date& operator-=(int day)
{
_day -= day;
while (_day <= 0)
{
--_month;
if (_month == 0)
{
--_year;
_month=12;
}
_day += GetMonthDay(_year, _month);
}
return *this;
}
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1(2023, 4, 11);
d1.Print();
Date d2(d1);//构造
d2.Print();
Date d3(2023,6,11);
d3.Print();
d3 = d1;//赋值,拷贝
d3.Print();
cout << (d1 < d2) << endl;
cout << (d1 > d2) << endl;
cout << (d1 == d2) << endl;
cout << (d1 <= d2) << endl;
Date d4 = d1;//拷贝构造
d4.Print();
Date d5(2023, 6.1);
d5.Print();
int day = d5 - d1;
cout << day << endl;
return 0;
}
注意:
1.不能通过连接其他符号来创建新的操作符,如@
2.重载运算符必须有一个类类型或者枚举类型的操作数。
3.用于内置类型的操作符,其含义不能改变,例:内置的整形+,不能改变其含义。
4.作为类成员的重载函数时,其形参看起来比操作数数目少1成员函数的操作符有一个默认的形参this,限定为第一个形参。
例如:bool operate<(const Date& d)
实际上是:bool operate<(Date* this,const Date& d)
在函数体里的数据成员默认是this指针所指向的,谁调用函数this就指向谁。
5.(.*)、(::)、(sizeof)、(?:)、(.)这五个(括号里的)运算符不能重载。
注意:第一个是 .*(点 星号)