日期类的-=day和-day
-=day虽然思路和+=差不多,但是逻辑却比+=难搞一些,建议仔细思考后在上手写。
// 日期-=天数
Date& Date::operator-=(int day)
{
// 当减的天数为负时的操作
if (day < 0) {
this += (-day);// 复用了刚才写的+=
return this;
}
_day -= day;
while (_day < 1) {
--_month;
if (_month == 0) {
--_year;
_month = 12;
}
day += GetMonthDay(_year, _month);
}
return *this;
}
在给_day+=天数时,注意加的是上个月的天数,并非本月天数。写了-=,-的实现也就是简单的复用操作了:
// 日期-天数
Date Date::operator-(int day)
{
Date tmp(*this);
tmp -= day;
return tmp;
}
返回值是否引用返回和+=day和+day是同理的。
前置++和后置++
知道内置类型的前置++和后置++吗?如++a,a++等,它们的作用都是给变量a自增1,学了这么长时间,你是否对它们的区别了如指掌。本篇我们讲的是自定义类型的自增,如,日期类,我们要给一个自定义类型(日期类)自增,但计算机并不知道日期自增的规则,这时就需要人为提供内置类型的自增运算符。其实,上面刚刚讲过复用,我们直接复用+=和-=就可以了,你想想,什么是++?什么是--?不就是+=1和-=1嘛!
// 前置++:返回+1之后的结果
Date& Date::operator++()
{
this += 1;
return this;
}
如果不提供参数,在C++的定义之下,默认就是放到对象前面的重载运算符:++d,但如果单将一个运算符放到对象后面构成运算符重载应该怎么办呢?看看C++提供的解决方式:
// 后置++:自增,返回自增之前的拷贝
Date Date::operator++(int)
{
Date tmp(this); this += 1;
return tmp;
}
前置--和后置--
不想多说了,四个字——同理,复用!
// 前置--
Date& Date::operator--()
{
this -= 1;
return this;
}
// 后置--
Date Date::operator--(int)
{
Date tmp(this); this -= 1;
return tmp;
}
注意区分前置和后置的区别,控制下返回值是否引用返回就行。
比大小运算符的重载
为什么要给日期提供比大小重载,因为内置类型无法完成比较日期的任务。比大小需要提供的重载函数就多了,包括 <,<=,==,>,>=,!= ,一套写下来,岂不是能把人累瘫,别着急,实际上,需要你完成的实际上只有两个,> 和 ==,当然你选择 < 和 ==,或者 <,!= 统统都可以,如果还没想通,没关系,来看看我是如何实现的,这里以> 和 ==为例。
// >运算符重载
bool Date::operator>(const Date& d)
{
if (_year > d._year
|| _year == d._year && _month > d._month
|| _year == d._year && _month == d._month && _day > d._day) return true;
return false;
}
// ==运算符重载
bool Date::operator==(const Date& d)
{
return _year == d._year
&& _month == d._month
&& _day == d._day;
}
这里是对于>和==的重载,其中逻辑不难理解。
// >=运算符重载
bool Date::operator>=(const Date& d)
{
return this > d || this == d;
}
发现C++运算符重载和复用的魅力了吗?
如果此时你需要一个 < 重载:
// <运算符重载
bool Date::operator<(const Date& d)
{
return !(this > d || this == d);
}
如果此时你需要一个 <= 重载:
// <=运算符重载
bool Date::operator<=(const Date& d)
{
return !(*this > d);
}
如果此时你需要一个 != 重载:
// !=运算符重载
bool Date::operator!=(const Date& d)
{
return !(*this == d);
}
如果……哦,已经没有如果了,这就是所有的比大小运算符重载🙂,很有意思吧。
日期-日期返回天数
日期减日期为的是计算两个日期之间的天数间隔。对于日期相减,这里提供了两种实现方案。
暴力++法
找出日期中小的那个,然后通过记录每次++的次数n来记录两日期之间的间隔,同时设置一个变量flag来记录两个日期之间的差是正的还是负的。
// 日期-日期 返回天数
int Date::operator-(const Date& d)
{
Date max = this;// 假设大的那个是this
Date min = d;
int flag = 1;
int n = 0;
if (this < d) { //判断并重置max和min以及日期间隔正负
max = d;
min = this;
flag = -1;
}
while (min != max) {
++min;
++n;
}
return n * flag;
}