Date类
判断 大于 小于 等于 等等运算符重载函数
我们先实现一个 > 的运算符重载,然后再实现一个 == 的运算符重载:
bool Date::operator>(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 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);
}
利用这样的逻辑,我们就可以这样写:
bool Date::operator<=(const Date& d)
{
return !(*this > d);
}
bool Date::operator>=(const Date& d)
{
return !(*this < d);
}
bool Date::operator!=(const Date& d)
{
return !(*this == d);
}
需要注意的是:上述后面 运算符重载函数 的实现技巧不仅仅可以用在 Date 简单简单类当中,因为后序的技巧只是在调用 对应的重载函数。所以这种技巧在如何类当中都可以使用。
其他功能函数实现
日期 + 天数 计算日期函数
首先确定的是每一个月的 天数不统一,而且有平年和闰年的区分2月的天数,所以我们先写一个函数来获取某一个月的 天数:
创建一个数组,下标 代表 月份,元素的值代表 这个月的天数:
static int array[] = {0,31,28,31,30,31,31,30,31,31,30,31,30,31};
直接把这个数组写在静态区,因为这个函数会被调用很多次,每次都需要创建这个数组的话很麻烦,所以我们直接创建静态的。
然后是判断闰年:
if(month == 2 && ((year % 4 == 0) || (year % 100 != 0) || (year % 400 == 0)))
{
return 29;
}
else
{
return array[month];
}
当我们拿到 一个月的天数的时候,我们就可以直接进行操作了,我们先直接把 需要加的天数直接加载 日期 的 _day 成员中,然后判断此时是否超出当月的天数,如果超出,_day 就减掉 当月的天数,_month++,然后再次判断,如果再超,就再减,如果不超说明就计算计算完成。如果上述月超了13,那么_year++。
下述代码的实现是有问题的:
Date Date::operator+(int day)
{
_day += day;
while (_day > GetMonthDate(_year, _month))
{
_day -= GetMonthDate(_year, _month);
_month++;
if (_month >= 13)
{
_month = 1;
_year++;
}
}
return *this;
}
这样写有一个问题,如下图:
我们只写了 d1 + 100 ,但是我们发现 d1 被修改了,其实是我们上述直接 对 _day 进行修改,我们应该把计算好的值作为函数的返回值。
所以,我们上诉实现的其实不是 + ,其实是 += :
Date Date::operator+=(int day)
{
_day += day;
while (_day > GetMonthDate(_year, _month))
{
_day -= GetMonthDate(_year, _month);
_month++;
if (_month >= 13)
{
_month = 1;
_year++;
}
}
return *this;
}
接下来我们对这个函数进行修改,实现 + 的重载:
Date Date::operator+(int day)
{
Date tmp(*this);
tmp->_day += day;
while (tmp->_day > GetMonthDate(_year, _month))
{
tmp->_day -= GetMonthDate(_year, _month);
tmp->_month++;
if (tmp->_month >= 13)
{
tmp->_month = 1;
tmp->_year++;
}
}
return tmp;
}
我们在 + 重载函数中创建一个 Date对象-tmp,然后把 当前对象拷贝给 这个tmp 对象,我们修改就修改这个 tmp 对象当中的 值,最后返回这个 tmp 就行了。
输出:
我们来看这个场景,当我们调用如下函数的时候,d3 是调用拷贝构造函数在创建,还是通过赋值来创建呢?
Date d3 = d1 + 100;
其实是 调用构造函数 来创建,因为此时编译器会做处理,把这个代码变成 如下来进行执行:
Date d3(d1 + 100);
+ 重载还可以这样写:
Date Date::operator+(int day)
{
Date tmp(*this);
tmp += day;
return tmp;
}
可以服用 += 重载函数。
前置++ 和后置++ 的实现
// 前置++
Date& Date::operator++()
{
*this += 1;
return *this;
}
// 后置++
Date Date::operator++(int)
{
Date tmp(*this);
*this += 1;
return tmp;
}
需要注意的是,前置后置 是 通过参数来构成重载,如 d1++;
- ++d1 会转换为 d1.operator++()
- d1++ 会转换成 d1.operator(0)
上述增加的int 不是为了接收具体的值,仅仅是为了占位,跟前置结点构成函数重载。