C++:日期类的实现

日期类的实现

实现日期类,就是实现其中的几个默认的成员函数以及一些运算符的重载的实现。

构造函数

使用初始化成员列表初始化年月日,并且对日期的非法性做以判断。

Date::Date(int year,int month,int day)
    :_year(year)
     ,_month(month)
     ,_day(day)
{
    if(!IsValid())
    {
        assert(false);
    }
}

这里对日期的非法性判断,主要代码如下:

bool Date::IsValid()
{
    return _year>=1900 && 
        _month>0 && _month<13 &&
        _day>0 && _day<=GetMonthDay(_year,_month);
}
//该函数主要用来实现获取当月的天数(受闰年的影响)
int Date::GetMonthDay(int year,int month)
{
    int arr[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
    if(month==2 && IsLeap(year))
    {
        ++arr[2];
    }
    return arr[month];
}
//判断该年是否是闰年
bool Date::IsLeap(int year)
{
    return (year%4==0 && year%100!=0) || year%400==0;
}
//打印函数
void Date::Show()
{
    cout<<_year<<"-"<<_month<<"-"<<_day<

析构函数

析构函数主要是用来做清理工作的,这里并不需要清理,所以简单写一句输出语句,证明调用过。

Date::~Date()
{
    cout<<"~Date()"<

拷贝构造

拷贝构造是为了对同一类的对象进行初始化。

//拷贝构造
Date::Date(const Date& d)
{
    cout<<"Date(Date& d)"<

赋值运算符的重载

//d1 = d2
Date& Date::operator=(const Date& d)
{
    if(*this!=d)
    {
        _day=d._day;
        _month=d._month;
        _day=d._day;
    }
    return *this;
}

运算符的重载

主要实现了以下运算符的重载:
C++:日期类的实现_第1张图片

代码如下;
== / !=


//==和!=运算符重载主要实现了判断两个日期是否相等。
//d1 == d2
bool Date::operator==(const Date& d)
{
    if(_year==d._year && _month==d._month && _day==d._day)
    {
        return true;
    }
    return false;
}
//d1 != d2
bool Date::operator!=(const Date& d)
{
    if(_year==d._year && _month==d._month && _day==d._day)
    {
        return false;
    }
    return true;
}

: > / >= / < / <=

//d1 > d2 判断第一个日期是否大于第二个日期,通过比较年月日的大小
bool Date::operator>(const Date& d)
{
    if(_year==d._year)
    {
        if(_month==d._month)
        {
            if(_day>d._day)
            {
                return true;
            }
        }
        else if(_month>d._month)
        {
            return true;
        }
    }
    else if(_year>d._year)
    {
        return true;
    }
    return false;
}

// d1 >= d2 通过将大于等于转化为 不小于
bool Date::operator>=(const Date& d)
{
    return !(*this//d1 < d2 通过将小于转换为 既不等于也不大于
bool Date::operator<(const Date& d)
{
    return !(*this==d) && !(*this>d);
}
//d1 <= d2 通过将小于等于转换为 不大于
bool Date::operator<=(const Date& d)
{
    return !(*this>d);
}

: + / += / - / -=

//d1 + 10 +主要时通过+=来实现
Date Date::operator+(int day)
{
    Date tmp(*this);
    tmp+=day;
    return tmp;
}
//d1 += 10 
//这里采取的思路:先将要加的天数加上,如果天数超过该月的天数,就将月数进一,
//并且将该月的天数减掉。如果月数已经加到大于12了,就将年进一,并且将月置一。
Date& Date::operator+=(int day)
{
    _day+=day;
    while(_day>GetMonthDay(_year,_month))
    {
        _day -= GetMonthDay(_year, _month);
        _month+=1;
        if(_month>12)
        {
            _year+=1;
            _month = 1;
        }
    }
    return *this;
}
//d1 - 10 同样,-也是通过-=来实现
Date Date::operator-(int day)
{
    Date tmp(*this);
    tmp -= day;
    return tmp;
}
//d1 -= 10 
//这里采取的思路是:如果天数减不够就向上一个月借天数,
//如果月数借到0,就向年借一,并且将月置为12
//此时再进行天数之间的减法
Date& Date::operator-=(int day)
{
    while(_day<=day)
    {
        _month-=1;
        if(_month==0)
        {
            _year-=1;
            _month=12;
        }
        _day+=GetMonthDay(_year,_month);
    }
    _day-=day;
    return *this; 
}

//d1 - d2 两个日期对象的减法,返回值是相差得天数
//采取的思路是:默认第一个日期比第二个日期大;
//如果第一个日期小于第二个日期,就将flag置为-1.
//让小的那个日期一直自增至与大的日期相等时,加得次数就是相差得天数
int Date::operator-(const Date& d)
{
    Date max(*this);
    Date min(d);
    int flag=1;
    if((*this)<d)
    {
        max=d;
        min=*this;
        flag=-1;
    }
    int count=0;

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

    return flag*count;
}

:前置++/后置++/前置–/后置–
后置++/后置–传参数是为了区别前置与后置得区别。

//++d1 通过+=来实现 直接改变*this值
Date& Date::operator++()
{
    *this+=1;
    return *this;
}

//d1++  改变*this值,但是返回的是+=前的值
Date Date::operator++(int)
{
    Date tmp(*this);
    *this+=1;
    return tmp;
}
//--d1
Date Date::operator--()
{
    *this-=1;
    return *this;
}
//d1--
Date Date::operator--(int)
{
    Date tmp(*this);
    *this-=1;
    return tmp;
}

运算符的重载看起来很多,但是我们实现起来如果注重一下实现的顺序,就会发现实现的运算符只有几个,其余的运算符的重载可以依赖于其中某几个的实现。

你可能感兴趣的:(C++)