C++类和对象(二) - 日期类的实现

x33g5p2x  于2021-11-09 转载在 C/C++  
字(4.1k)|赞(0)|评价(0)|浏览(365)

前言:本文将介绍Date类的具体实现,通过日期类的简单实现帮助我们完整复习一遍类的“六大默认成员函数”。

1.日期类的定义

class Date
{
public:
    // 获取某年某月的天数
    int GetMonthDay(int year, int month);

    // 全缺省的构造函数
    Date(int year=1988, 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);

    // >=运算符重载
    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);

    //定义一个函数打印看看
    void print()
    {
        cout << _year << " " << _month << " " << _day << endl;  
    }
private:
    int _year;
    int _month;
    int _day;
};

2.日期类成员函数具体实现

2.1准确获取某年某月有多少天

这里考虑下闰年的情况,然后用数组简单映射下就好了

int Date::GetMonthDay(int year, int month)
{
    //记录每月天数
    int Month[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
    //遇见闰年,二月天数置29
    if (month == 2 && ((year %4 == 0 && year % 100 != 0) || (year % 400 == 0)))  return 29;
    return Month[month];
}

2.2日期类构造函数

Date::Date(int year, int month, int day)
{
    _year = year;
    _month = month;
    _day = day;
    //检测下日期是否合法
    if (month < 1 || month>12 || day<0 || day>GetMonthDay(year,month))  cout << "非法日期" << endl;
}

2.3日期类拷贝构造

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

2.4赋值运算符重载

类体外定义是成员函数返回值类型+类名::函数名(形参列表)

Date& Date:: operator=(const Date& d)
{
    _year = d._year;
    _month = d._month;
    _day = d._day;
    return *this;   //这个可不能少,少了遇上连续赋值语句a=b=c会出错。
}

2.5+=运算符重载

考虑越界情况

  • 如果_day加了整数以后,<=该月最大天数,则不需要修改,直接返回该日期.
  • 如果_day加了整数以后,>该月最大天数,则_day减去新的月所拥有的最大天数,然后该月加1,.
  • 如果执行了第二步后,_day仍大于新的月所拥有天数,继续执行第二步,并且循环.
Date& Date:: operator+=(int day)
{
    //先把加的天数算进来
    _day += day;
    //考虑加了这个天数之后,_day是否合法,不合法就给他转一下
    while (_day > GetMonthDay(_year, _month))
    {
        _day -= GetMonthDay(_year, _month);
        _month++;
        if (_month == 13)
        {
            _month = 1;
            _year++;
        }
    }
    return *this;
}

2.6+运算符重载

复用!!!

Date Date::operator+(int day)
{
    //+和+=区别无非就是一个返回的是运算之后的结果,一个返回的是运算之前的结果
    Date tmp(*this);
    *this += day;
    return tmp;
}

2.7-=运算符重载

考虑越界情况,与+=同理

Date& Date::operator-=(int day)
{
    _day -= day;
    while (_day < 1)
    {
        _month--;
        if (_month < 1)
        {
            _month = 12;
            _year--;
        }
        _day += GetMonthDay(_year, _month);
    }
    return *this;
}

2.8+运算符重载

复用!!!

Date Date::operator+(int day)
{
    //+和+=区别无非就是一个返回的是运算之后的结果,一个返回的是运算之前的结果
    Date tmp(*this);
    *this += day;
    return tmp;
}

2.9-运算符重载

复用!!!

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

2.10前置++运算符重载

复用!!!

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

2.11前置–运算符重载

复用!!!

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

2.12后置-- 运算符重载

复用!!!

Date& Date::operator--(int)  //这个int用于区分前置还是后置
{
    Date tmp(*this);
    *this -= 1;
    return tmp;
}

2.13后置++运算符重载

复用!!!

Date& Date::operator++(int)  //这个int用于区分前置还是后置
{
    Date tmp(*this);
    *this += 1;
    return tmp;
}

2.14>运算符重载

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;
}

2.15==运算符重载

bool Date::operator==(const Date& d)
{
    if (_year == d._year && _month == d._month && _day == d._day)  return true;
    return false;
}

2.16>=运算符重载

复用!!!

bool Date::operator>=(const Date& d)
{
    if (*this > d || *this == d) return true;
    return false;
}

2.17<运算符重载

复用!!!

bool Date::operator<(const Date& d)
{
    if (!(*this >= d))  return true;
    return false;
}

2.18<=运算符重载

复用!!!

bool Date::operator<=(const Date& d)
{
    if (!(*this > d))  return true;
    return false;
}

2.19!=运算符重载

复用!!!

bool Date::operator!=(const Date& d)
{
    return !(*this == d);
}

2.20.计算两个日期之间的间隔天数,日期减去日期

直接从小的日期开始,通过while循环往上加,然后计数,直到等于大的日期为止。

计数结束时,所计的数字便是我们想要的间隔天数。

int Date::operator-(const Date&d)
{
    Date max(*this);
    Date min(d);
    int n = 1;
    if (max < min)
    {
        Date tmp(max);
        max = min;
        min = tmp;
        n = -1;
    }

    int count = 0;
    while (min<=max)
    {
        count++;
        min++;
    }
    return count*n;
}

学以致用一波,精心为大家准备了几道日期类编程题,不妨练练手,完全相似的哦!!!

牛客:日期差值

牛客:计算一年的第几天

牛客:日期累加

牛客:打印日期

3.源码链接

点击跳转代码仓库

感谢您的阅读!!!如果内容对你有帮助的话,记得给我三连(点赞、收藏、关注)——做个手有余香的人。

相关文章