C++日期类运算符重载方式

软件发布|下载排行|最新软件

当前位置:首页IT学院IT技术

C++日期类运算符重载方式

安河桥畔   2023-03-20 我要评论

构造函数

定义一个全缺省的构造函数,函数体内判断当前日期是否合法,如果是非法日期,则初始化为2022,1,1

Date(int year=2022, int month=1, int day=1)
        :_year(year)
        , _month(month)
        , _day(day)
    {
        if (year <1 || month < 1 || month>12 || day<1 || day>GetDayOfMonth(year,month))
        {
            _year = 2022;
            _month = 1;
            _day = 1;
        }
    }

拷贝构造

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

赋值运算符重载

赋值运算符编译器会默认生成,对于日期类可以不用自己定义,自己定义需要注意三点:

  • 参数和返回值都是类类型的引用
  • 判断是否为自己给自己赋值,因为两对象不能直接比较,所以判断时用地址
  • 为了支持连续赋值,必须返回*this
    Date& operator=(const Date& d)
    {
        //不能用对象直接比较,只能比较地址
        //if (d != (*this))
        if(&d!=this)
        {
            _year = d._year;
            _month = d._month;
            _day = d._day;
        }
        return *this;
    }

“+” 日期+天数

"+“与”+=“区分,”+"不改变原变量的值,只是通过返回值返回,所以这里要定义一个临时变量temp,由于temp是保存在栈上的临时变量,所以返回值为Date类型,不能返回引用

先判断正负,如果加的数是负数,则复用"-"的重载

加完后判断_day的合法性,如果_day非法,_day减去当前月份的天数,月份增加,直到日期合法

    //日期+天数
    Date operator+(int day)
    {
        //不能改变原有日期,所以要定义临时变量
        //临时变量不能返回引用
        if (day < 0)
        {
            day = -day;
            return *this - day;
        }
        Date temp=*this;
        temp._day += day;
        while (temp._day > GetDayOfMonth(_year, _month))
        {
            temp._day -= GetDayOfMonth(temp._year,temp._month);
            temp._month++;
            if (temp._month > 12)
            {
                temp._month = 1;
                temp._year++;
            }
        }
        return temp;
    }

“-” 日期-天数

与"+"同原理,如果_day减为0或者负数,先将月份下调一个月,再将日加上上调后月份的天数,如8月0日表示7月31,8月-1日,则表示7月30日。

    //日期-天数
    Date operator-(int day)
    {
        if (day < 0)
        {
            day = -day;
            return *this + day;
        }
        Date temp = *this;
        temp._day -= day;
        while (temp._day <= 0)
        {
            temp._month--;
            if (temp._month < 1)
            {
                temp._year--;
                temp._month = 12;
            }
            temp._day += GetDayOfMonth(temp._year ,temp._month);
        }
        return temp;
    }

“+=” 日期+=天数

"+=“与”+“的区别是,加后要个自己赋值,所以返回类类型对象的引用,可以复用”=“和”+"的重载

    //日期+=天数
    Date& operator+=(int days)
    {
        //复用=和+
        //这里要先将加的和赋值给*this,再返回
        //非常量左值引用只能引用非常量左值
        //如果要直接return(*this + days),返回值类型应为Date&&
        *this = *this + days;
        return * this;
    }

“-=” 日期-=天数

    //日期-=天数
    Date& operator-=(int days)
    {
        *this = *this - days;
        return *this;
    }

前置"++"

前置"++"返回的是加一后的值,可以直接给*this加一后返回

    //前置++
    Date& operator++()
    {
        *this += 1;
        return *this;
    }

后置"++"

C++中,后置"++“参数加一个int,无实际意义,区分前置与后置”++“,由于后置”++"要返回的是自增之前的值,所以要定义一个临时变量,自增后返回该临时变量的值

    //后置++
    //
    Date operator++(int)
    {
        //返回的是自增之前的值
        Date temp = *this;
        *this += 1;
        return temp;
    }

前置"–"

与前置"++"原理相同

    //前置--
    Date& operator--()
    {
        *this -= 1;
        return *this;
    }

后置"- -"

与后置"++"原理相同

    //后置--
    Date operator--(int)
    {
        Date temp = *this;
        *this-= 1;
        return temp;
    }

“==”

判断每变量是否相等

    //==
    bool operator==(Date& d)const
    {
        return d._year == _year &&
            d._month == _month &&
            d._day == _day;
    }

“>”

从年到月日依次判断

    //>
    bool operator>(Date& d)const
    {
        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;
        }
        else
        {
            return false;
        }
    }

“<”

    //<
    bool operator<(Date& d)const
    {
        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;
        }
        else
        {
            return false;
        }
    }

“-” 日期-日期

定义一个计数器统计从小的日期到大的日期需要自增多少次

    int operator-(const Date& d)const
    {
        int count = 0;
        Date start(*this);
        Date end(d);
        //保证大的日期减小的日期
        if (start>end)
        {
            Date temp = end;
            end = start;
            start = temp;
        }
        while(end>start)
        {
            start++;
            count++;
        }
        return count;
    }

设置年、月、日

对外部提供修改对象值的接口

    void SetYear(int year)
    {
        _year = year;
    }

    void SetMonth(int month)
    {
        _month = month;
    }

    void SetDay(int day)
    {
        _day = day;
    }

获取年、月、日

向外部提供获取类成员变量值的接口

    int GetYear()const
    {
        return _year;
    }

    int GetMonth()const
    {
        return _month;
    }
    
    int GetDay()const
    {
        return _day;
    }

判断闰年

判断闰年,可以定义为private,不用暴露给外部

    bool IsLeapYear(int year)
    {
        if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
        {
            return true;
        }
        return false;
    }

获取当前月天数

定义一个数组保存每月的天数,根据传进来的年和月返回当前月份的天数

    //获取当前月份的天数
    int GetDayOfMonth(int year, int month)
    {
        int arr[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
        if (IsLeapYear(year))
        {
            arr[2] = 29;
        }
        return arr[month];
    }

日期类完整代码

class Date
{
public:
    //全缺省构造函数
    Date(int year=2022, int month=2, int day=2)
        :_year(year)
        , _month(month)
        , _day(day)
    {
        if (year <1 || month < 1 || month>12 || day<1 || day>GetDayOfMonth(year,month))
        {
            _year = 2022;
            _month = 1;
            _day = 1;
        }
    }
    //拷贝构造
    Date(const Date& d)
    {
        _year = d._year;
        _month = d._month;
        _day = d._day;
    }
    //析构——无实际意义
    ~Date()
    {
        cout << "~Date()" << endl;
    }

    //赋值运算符重载(不写也可以,编译器会默认生成)
    Date& operator=(const Date& d)
    {
        //不能用对象直接比较,只能比较地址
        //if (d != (*this))
        if(&d!=this)
        {
            _year = d._year;
            _month = d._month;
            _day = d._day;
        }
        return *this;
    }

    //日期+天数
    Date operator+(int day)
    {
        //不能改变原有日期,所以要定义临时变量
        //临时变量不能返回引用
        if (day < 0)
        {
            day = -day;
            return *this - day;
        }
        Date temp=*this;
        temp._day += day;
        while (temp._day > GetDayOfMonth(_year, _month))
        {
            temp._day -= GetDayOfMonth(temp._year,temp._month);
            temp._month++;
            if (temp._month > 12)
            {
                temp._month = 1;
                temp._year++;
            }
        }
        return temp;
    }

    //日期-天数
    Date operator-(int day)
    {
        if (day < 0)
        {
            day = -day;
            return *this + day;
        }
        Date temp = *this;
        temp._day -= day;
        while (temp._day <= 0)
        {
            temp._month--;
            if (temp._month < 1)
            {
                temp._year--;
                temp._month = 12;
            }
            temp._day += GetDayOfMonth(temp._year ,temp._month);
        }
        return temp;
    }

    //日期+=天数
    Date& operator+=(int days)
    {
        //复用=和+
        //这里要先将加的和赋值给*this,再返回
        //非常量左值引用只能引用非常量左值
        //如果要直接return(*this + days),返回值类型应为Date&&
        *this = *this + days;
        return * this;
    }

    //日期-=天数
    Date& operator-=(int days)
    {
        *this = *this - days;
        return *this;
    }

    //前置++
    Date& operator++()
    {
        *this += 1;
        return *this;
    }
    //后置++
    //C++语法,后置++参数加一个int,无实际意义,区分前置与后置++
    Date operator++(int)
    {
        //返回的是自增之前的值
        Date temp = *this;
        *this += 1;
        return temp;
    }

    //前置--
    Date& operator--()
    {
        *this -= 1;
        return *this;
    }

    //后置--
    Date operator--(int)
    {
        Date temp = *this;
        *this-= 1;
        return temp;
    }
    //==
    bool operator==(Date& d)const
    {
        return d._year == _year &&
            d._month == _month &&
            d._day == _day;
    }

    //>
    bool operator>(Date& d)const
    {
        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;
        }
        else
        {
            return false;
        }
    }

    //<
    bool operator<(Date& d)const
    {
        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;
        }
        else
        {
            return false;
        }
    }
    //日期-日期 即还有多少天到某一天 
    int operator-(const Date& d)const
    {
        int count = 0;
        Date start(*this);
        Date end(d);
        //保证大的日期减小的日期
        if (start>end)
        {
            Date temp = end;
            end = start;
            start = temp;
        }
        while(end>start)
        {
            start++;
            count++;
        }
        return count;
    }

    //设置年、月、日接口
    void SetYear(int year)
    {
        _year = year;
    }

    void SetMonth(int month)
    {
        _month = month;
    }

    void SetDay(int day)
    {
        _day = day;
    }

    //获取年、月、日接口
    int GetYear()const
    {
        return _year;
    }

    int GetMonth()const
    {
        return _month;
    }
    
    int GetDay()const
    {
        return _day;
    }
private:
    int _year;
    int _month;
    int _day;
    //判断闰年
    bool IsLeapYear(int year)
    {
        if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
        {
            return true;
        }
        return false;
    }

    //获取当前月份的天数
    int GetDayOfMonth(int year, int month)
    {
        int arr[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
        if (IsLeapYear(year))
        {
            arr[2] = 29;
        }
        return arr[month];
    }
};

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

Copyright 2022 版权所有 软件发布 访问手机版

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 联系我们