日期----类之实现

前言

这是一篇对于日期类的实现练习,是上一篇文章的一个小小分支默认函数;


类的定义和各种操作符声明

在上文默认函数中我们已经详细说明了需要实现哪些操作符和声明,所以这里便直接写出.

class Date
{
public:
    // 获取某年某月的天数
    int GetMonthDay(int year, int month);
    // 全缺省的构造函数
    Date(int year = 1900, int month = 1, int day = 1);
    // 拷贝构造函数
    Date(const Date& d);
    // 赋值运算符重载
  // d2 = d3 -> d2.operator=(&d2, d3)
    Date& operator=(const Date& d);
    // 日期+=天数
    Date& operator+=(int day);
    // 日期+天数
    Date operator+(int day);
    // 日期-天数
    Date operator-(int day);
    // 日期-=天数
    Date& operator-=(int day);
    // 前置++
    Date& operator++();
    // 后置++
    Date operator++(int);
    // 后置--
    Date operator--(int);
    // 前置--
    Date& operator--();
    // >运算符重载
    bool operator>(const Date& d);
    // ==运算符重载
    bool operator==(const Date& d);
    // >=运算符重载
    inline bool operator >= (const Date& d);
    // <运算符重载
    bool operator < (const Date& d);
    // <=运算符重载
    bool operator <= (const Date& d);
    // !=运算符重载
    bool operator != (const Date& d);
    // 日期-日期 返回天数
    int operator-(const Date& d);
private:
    int _year;
    int _month;
    int _day;
};

获取某年的某月有多少天

我们都知道一年有十二个月,其中大部分是30天和31天,而二月有时候是29天,有时候是28天,所以我们需要单独判断.而实现这个函数的思路其实我们可以用数组进行映射:

int Date:: GetMonthDay(int year, int month)
{
    //数组下标代表1-12月
    int month_day[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
    //如果是2月,并且当年是闰年,则返回29天.
    if (month == 2 && ((year % 100 != 0 && year % 4 == 0) || (year % 400 == 0)))
        return 29;
    //其余情况,直接返回数组下标对应的值
    return month_day[month];
}

构造函数的实现

这个在上文我们已经讲解,这里便直接实现

Date:: Date(int year, int month, int day)
{
    _year = year;
    _month = month;
    _day = day;
    if (year<0 || month < 0 || month>13 || day>GetMonthDay(year, month))    //这一步可以检测日期有效性
        cout << _year << "/" << _month << "/" << day << "--->非法日期" << endl;
}

拷贝构造

同样的,上文已经讲解过,这里便直接实现

Date:: Date(const Date& d)
{
    _year = d._year;
    _month = d._month;
    _day = d._day;
}

赋值运算符重载

同样的,上文已经讲解过,这里便直接实现

Date& Date:: operator=(const Date& d)
{
    _year = d._year;
    _month = d._month;
    _day = d._day;
    return *this;
}

+=整型实现

这个操作的功能是实现对象向未来前进整数天.实现思路如下:

  • 如果_day加了整数以后,小于等于该月最大天数,则不需要修改,直接返回该日期.

  • 如果_day加了整数以后,大于该月最大天数,则_day减去新的月所拥有的最大天数,然后该月加1,.

  • 如果执行了第二步后,_day仍大于新的月所拥有天数,继续执行第二步,并且循环.

Date& Date:: operator+=(int day)
{
    _day += day;   //先加整数
    int n = 0;
    while (_day > (n = GetMonthDay(_year, _month)))   //检查_day加了整数以后,是否日期合法.
    {
        _day -= n;   //如果大于该月,则_day减去该月最大天数.
        _month++;    //然后_month++.
        if (_month == 13) _year++,_month = 1;  //如果_month加到了13,则年需要++,并且_month再次变1
    }
    return *this;
}

+整型实现

这个操作的功能和上面很像,但是它自己不变.很多人的思路可能是,先创建个临时Date对象,然后临时对象执行和上面一样的代码,最后返回临时对象,这个思路是没错的,但是我们可以更简洁,怎么简洁呢?那就是直接复用上面操作符

Date Date:: operator+(int day)
{
	Date tmp(*this);
    tmp += day;    //tmp+=整数后,tmp就直接向未来前进了day天,然后我们直接返回tmp就行.
    return tmp;
}

-=整型实现

-=实现意义是向过去回退整型天,而他实现的思路和+=相似,只不过是反过来,博主就不再详细解释,大家可以仔细思考

Date& Date:: operator-=(int day)
{
    _day -= day;   //先减整数
    while (_day < 0)   //检查_day加了整数以后,是否日期合法.
    {
        _month--; //如果不合法,这_month减少一个月
        if (_month == 0) _year--,_month = 12;  //如果_month减少到了0,则年需要--,并且_month再次变12        
        _day += GetMonthDay(_year,_month);  //然后加上新月的最大天数   
    }
    return *this;
}

-整型实现

我们这里仍然模拟+的实现,直接复用-=就行.

Date Date:: operator-(int day)
{
    Date tmp(*this);
    tmp -= day;
	return tmp;
}

前置++

按照原来的固有思路,我们可能会先让_day+1,然后判断是否合法,再判断_month_year是否需要调整,其实我们还是可以直接复用前面的操作符.

Date& Date:: operator++()
{
    *this+=1;
    return *this;
}

后置++

同样的,其仍可以复用

Date Date:: operator++(int)  //注意哦,这里必须有个 无用int形参,这是为了让编译器认识你所调用的是前置还是后置
{
    Date tmp(*this);
    *this+=1;
    return tmp;
}

前置–

继续复用

Date& Date:: operator--()
{
    *this-=1;
    return *this;
}

后置–

继续复用

Date Date:: operator--(int)  //注意哦,这里必须有个 无用int形参,这是为了让编译器认识你所调用的是前置还是后置
{
    Date tmp(*this);
    *this-=1;
    return tmp;
}

>重载

如果前者年 大于 后者年,返回true;

如果年相等,前者月 大于后者月,返回true;

如果年月相等,前者天 大于 后者天,返回true;

前三者除外后,返回false;

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& x2)
{
	return _year == x2._year && _month == x2._month && _day == x2._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);     // != 是 == 的取反,所以直接取反
}

日期减去日期

日期减去日期,也就是求两个日期之间间隔多少天,博主的思路是,直接从小的日期开始,循环加1,然后计数,直到等于大的日期为止.

int Date:: operator-(const Date& d)
{
	Date MAX(*this);
    Date MIN(d);
    int n = 1;
    if(MAX < MIN)    //如果前者比后者小,就交换,并且n变为-1;
    {
        Date tmp = MAX;
        MAX = MIN;
        MIN = tmp;
        n = -n;
    }
    int ans = 0;
    while(MIN != MAX)
    {
        MIN++;
        ans++;
    }
    return n*ans;
}
  • 27
    点赞
  • 10
    收藏
  • 打赏
    打赏
  • 18
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:撸撸猫 设计师:马嘣嘣 返回首页
评论 18

打赏作者

捕获一只小肚皮

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

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值