本篇文章将实现一个日期类,来为大家演示运算符重载的细则
1.赋值运算符重载
赋值运算符需要考虑的一点是连续赋值,因此需要考虑到返回值
// 赋值运算符重载
//d1 = d2 需要返回赋值后d1的值,函数结束后d1任然存在,可以返回引用
Date& operator=(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
return *this;
}
区分赋值运算符与拷贝构造函数
Date d1(2022,7,22);
Date d2 = d1;//调用拷贝构造
Date d3;
d3 = d1;//赋值运算符
对一个类进行初始化调用的是拷贝构造函数
如果一个类已经初始化完成,就是赋值运算符
2.日期+=天数
当天大于当前月数的最大天数时月进1,当月大于12时,年进1
+=需要对当前的日期进行改变
比如:
int i = 10;
i += 1;//i变成11
还需要考虑连续+=等情况,需要考虑返回值
3.日期+天数
加号的重载可以复用加等的
相加之后需要返回一个新的Date
// 日期+天数
// 复用+=
//d1 + day 返回一个新的Date
Date operator+(const int day)const
{
Date tempDate = *this;
tempDate += day;
return tempDate;
}
4.日期-=天数
减完后的天若小于0,则月份-1,天数加上当前月份的总天数,如果月份等于0,则年减一,月份变成12月
// 日期-=天数
Date& operator-=(const int day)
{
_day -= day;
while (_day <= 0 )
{
_month--;
if (_month == 0)
{
_month = 12;
_year--;
}
_day += GetMonthDay(_month);
}
return *this;
}
5.日期-天数
复用-=
Date operator-(const int day)const
{
Date tempDate = *this;
tempDate -= day;
return tempDate;
}
6.前置++、后置++
C++规定后置++重载时多增加一个int类型的参数,但调用函数时该参数不用传递,编译器自动传 递
// 前置++
//返回++后的值
Date& operator++()
{
*this += 1;
return *this;
}
// 后置++
//返回++前的值
Date operator++(int)
{
Date tempDate = *this;
*this += 1;
return tempDate;
}
7.前置--、后置--
与++类似
// 后置--
Date operator--(int)
{
Date tempDate = *this;
*this -= 1;
return tempDate;
}
// 前置--
Date& operator--()
{
*this -= 1;
return *this;
}
8.==运算符重载
// ==运算符重载
bool operator==(const Date& d)const
{
return d._year == _year && d._day == _day && d._month == _month;
}
9.>运算符重载
// >运算符重载
bool operator>(const Date& d)const
{
if (_year > d._year)
{
return true;
}
else if(_year == d._year)
{
if (_month > d._month)
{
return true;
}
else if (_month == d._month)
{
if (_day>d._day)
{
return true;
}
}
}
return false;
}
10.>=运算符重载
复用>和=运算符
// >=运算符重载
bool operator>=(const Date& d)const
{
if (*this > d)
{
return true;
}
else if(*this == d)
{
return true;
}
return false;
}
11.<运算符重载
复用>=运算符
// <运算符重载
bool operator<(const Date& d)const
{
return !( *this >= d);
}
12.<=运算符
// <=运算符重载
bool operator<=(const Date& d)const
{
if (*this <d ||*this == d)
{
return true;
}
return false;
}
13.!=运算符重载
bool operator!=(const Date& d)const
{
return !(*this == d);
}
14.日期-日期
用大的日期-=1 ,直到大的日期等于小的日期,期间用一个n记录它们相减的次数,n就是它们之间的差值
// 日期-日期 返回天数
int operator-(const Date d)const
{
int flag = 1;
Date big = *this;
Date little = d;
if (*this < d)
{
flag = 0;
big = d;
little = *this;
}
int n = 0;
while (big != little)
{
big -= 1;
n++;
}
if (flag == 0)
{
return -n;
}
return n;
}
15.取地址及const取地址操作符重载
//取地址及const取地址操作符重载
Date* operator&()
{
return this;
}
const Date* operator&()const
{
return this;
}
这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可,只有特殊情况,才需要重载,比如想让别人获取到指定的内容!
16.流提取与流插入运算符重载
C++在输入和输出的时候都不需要我们给出变量的类型这是为什么呢?
实际上是因为编译器把常见的内置类型都进行了运算符重载
比如:
int i = 10;
cout<<i;//实际上是调用 cout.operator<<(i);
如果我们需要用流提取和流插入的方式来输入输出Date类也需要进行重载
流提取和流插入运算符重载需要放在全局变量,因为我们需要让左操作数是cout有操作数是Date,如果放在类里实现,this就会默认为左操作数,这样使用流提取运算符的时候就会变成 d<<cout
全局函数不能放在.h文件,当不同.cpp文件包含这个.h文件的时候就会有多个相同的全局函数
//流提取运算符重载
std::ostream& operator<<(std::ostream& out, const Date& d)
{
out << d._year << "-" << d._month << "-" << d._day << endl;
return out;
}
//流插入运算符重载
std::istream& operator>>(std::istream& in, Date& d)
{
in >> d._year >> d._month >> d._day;
return in;
}