日期类的实现

前言:实现一个完整的日期类,来加强对这类的6个默认成员函数的认识。

目录

 构造函数

GetMonthDay函数中的三个细节:

打印函数

日期 += 天数

日期 + 天数

日期 -= 天数

日期 - 天数 

前置 ++

后置 ++

前置 -- 

 后置 -- 

日期类的大小关系比较 

>运算符的重载

==运算符的重载 

<运算符的重载

>=运算符的重载

 <=运算符的重载

!=运算符的重载

日期 - 日期

今天星期几 


日期类中所包含的成员函数和成员变量:

class Data
{
public:
    //构造函数
    Data(int year = 0, int month = 1, int day = 1);

    //赋值运算符的重载
    Data& operator=(const Data& d);

    //+=运算符的重载
    Data& operator+=(int day);
    //获得此年此月的天数
    int GetMonthDay(int year, int month)const;
    
    //+运算符的重载
    Data operator+(int day)const;

    //前置++重载
    Data& operator++();

    //后置++重载
    Data operator++(int);

    //-=运算符的重载
    Data& operator-=(int day);

    //-运算符的重载
    Data operator-(int day)const;

    //重载前置--

    Data& operator--();

    //后置--重载
    Data operator--(int);

    //>运算符重载
    bool operator>(const Data& d)const;

    //运算符==重载
    bool operator==(const Data& d)const;

    //运算符>=重载
    bool operator<=(const Data& d)const;

    //运算符<重载
    bool operator<(const Data& d)const;

    //运算符<=重载
    bool operator>=(const Data& d)const;

    //运算符!=重载
    bool operator!=(const Data& d)const;

    //日期-日期
    int operator-(const Data& d)const;

    //今天是星期几
    void IsWeekDay()const;

    //打印日期
    void Print()const;
   
private:
    int _year;
    int _month;
    int _day;
};
析构,拷贝构造,赋值重载可以不写,使用默认生成的即可

 构造函数

对象创建时,进行对象变量的赋值,需要先判断日期是否合理,进行后续构造。

因为函数声明(.h)与定义(.cpp)分离,所以定义需要指定函数的类域 类名::+函数名

int Data::GetMonthDay(int year, int month)const
{

     //数组存储平年每个月的天数
    const int days[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
    int day = days[month];
    if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
    {
        day += 1;//闰年二月的天数是29
    }
    return day;
}

Data::Data(int year, int month, int day)
{

     //判断日期是否合理之后进行赋值
    if (year >= 0 &&

       month > 0 && month < 13

       && day>0 && day <= GetMonthDay(year, month))
    {
        _year = year;
        _month = month;
        _day = day;
    }
    else
    {
        cout << "日期非法:";
        cout << _year << "-" << _month << "-" << _day << endl;
    }
}

GetMonthDay函数中的三个细节

1.用const修饰this指针,因为this不能被修改。

2.days数组最好用static修饰,这样在静态区存储,不会因为频繁调用而频繁创建。

3.判断平年还是闰年的天数时,先判断是否是二月,在进行平闰年的判断。

注:当函数声明和定义分开时,在声明时注明缺省参数,定义时就不能标出缺省参数。

打印函数

void Data::Print()const
{
    cout << _year << "年" << _month << "月" << _day << "日" << endl;
}

日期 += 天数

+=操作符,会改变对象变量的值。

实现思路:1.日期对象的天数加上天数  2.判断日期是否合理,若不合理(表示日满),天数-=这年这月的天数,然后月份month++,若month>12时,year++,month重新赋值为1(表示年满)。步骤2继续,直到日期合理为止。

Data& Data::operator+=(int day)
{
    if (day < 0)//这里表示+=的天数是一个负数,复用-=操作符
    {
        *this -= -day;
    }
    else
    {
        _day += day;
        while (_day > GetMonthDay(_year, _month))//不合理的日期继续执行
        {
            _day -= GetMonthDay(_year, _month);
            _month++;
            if (_month > 12)
            {
                _year++;
                _month = 1;
            }
        }
    }
    return *this;//this不会因为函数结束而销毁,可以用引用做返回值。
}

日期 + 天数

实现+,我们可以直接复用+=,但是需要注意,这个日期本身不会改变,例如:ret=i+1,i本身的值不会变。

Data Data::operator+(int day)const//this不会改变,用const修饰
{
    Data ret(*this);//利用this拷贝构造需要返回改变的ret
    ret += day;
    return ret;//ret出了函数作用域销毁,不可引用做返回值
}

日期 -= 天数

实现思路:1.日期对象的天数减上该天数  2.判断日期是否合理,若不合理,月份month--,day+=此年此月的天数,若month<1(表示该年已完) ,month=12,year--。继续执行步骤2,直到日期合理为止。

Data& Data::operator-=(int day)
{
    if (day < 0)//表示减一个负数,相当于+这个数的正数
    {
        *this += -day;//复用+=
    }
    else
    {
        _day -= day;//步骤1
        while (_day <= 0)//步骤2
        {
            _month--;
            if (_month < 1)
            {
                _year--;
                _month = 12;
            }
            _day += GetMonthDay(_year, _month);
        }
    }
    return *this;
}

日期 - 天数 

与+一样,我们复用-=,同样需要注意的问题和+的重载一样

Data Data::operator-(int day)const
{
    Data ret(*this);
    ret -= day;
    return ret;
}

前置 ++

一样可以复用+=,对象日期+1

Data& Data::operator++()
{
    *this += 1;
    return *this;//出了函数作用域,this不会销毁,引用做返回值
}

后置 ++

由于前置++和后置++的运算符均为++,为了区分它们的运算符重载,我们给后置++的运算符重载的参数加上一个int型参数,无需传实参,只是为了构成重载。

Data Data::operator++(int)
{
    Data ret(*this);
    *this += 1;
    return ret;
}

后置++也是需要返回加了之前的值,只能先用对象ret保存之前的值,然后对象日期加一,最后返回ret对象,ret出了函数作用域,销毁,不能引用做返回值

前置 -- 

可以复用-=,其他需要注意的和++一样

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

 后置 -- 

Data Data::operator--(int)
{
    Data ret(*this);
    *this -= 1;
    return ret;
}

日期类的大小关系比较 

日期类比较有六个(>   <   ==    !=   >=   <=),但是我们只需要实现两个,其他复用便可。

注:日期比较大小,说明本身都不会改变,都需要用cosnt修饰。

>运算符的重载

bool Data::operator>(const Data& d)const
{

    return _year > d._year || _month > d._month || _day > d._day;
}

==运算符的重载 

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

<运算符的重载

bool Data::operator<(const Data& d)const
{
    return !(*this > d || *this == d);
}

>=运算符的重载

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

 <=运算符的重载

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

!=运算符的重载

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

日期 - 日期

返回的是两个日期间隔的天数。

实现思路:让小的那个日期不断加1,也用一个count记录一下小的加1的次数,直到与大的那个相等,结束,此时count就是两个日期间隔天数。

若是第一个日期大于第二个日期,则返回这个差值的正值,若第一个日期小于第二个日期,则返回这个差值的负值。

int Data::operator-(const Data& d)const
{
    Data max = *this;
    Data min = d;
    int flag = 1;
    int count = 0;


    if (max < min)
    {
        max = d;
        min = *this;
        flag = -1;
    }


    while (max != min)
    {
        count++;
        min++;
    }
    return count*flag;
}
 

今天星期几 

1900,1,1是参考日期星期一,用需要判断星期几的日期-这个参考日期得到间隔天数,一周是7天,用得到的间隔天数%7(取值在0-6之间),就能得到星期几。

void Data::IsWeekDay()const
{
    int day=*this - Data(1990,1,1);//匿名对象生命周期就在这一行
    const char* days[7] = {"星期一","星期二", "星期三", "星期四", "星期五", "星期六", "星期天" };
    cout << days[day % 7] << endl;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值