通过对前面的学习,我们实现一个日期类来玩玩类的默认函数
我们要实现以下功能来模拟类的默认函数:
#include <iostream>
#include <assert.h>
using std::cout;
using std::cin;
using std::endl;
class Date
{
public:
Date (int year=0,int month=1,int day=0);
//1.要考虑到日期的合法性,如果不合法,置成0,1,1,实现全缺省参数
//2.由于在日期类,没有用到资源的开辟,所以我们可以使用编译器自动合成的拷贝构造,赋值运算符重载等。
//3.实现一个日期加上N天后,日期为多少
//4.实现一个日期减去N天后,日期为多少
//5.求两个日期之间相隔多少天
void Print();
// 析构、拷贝构造、赋值重载,可以不写,默认生成就够用;
// 像Stack才需要自己写这三个
//Date& operator+=(int day);
Date& operator+=(int day); //加一个数,对定义的类有实际的改变,相当于i=i+1;
Date operator+(int day); //加一个数,对定义的类没有实际的改变,相当于i+1;对i没有改变
Date& operator-=(int day); //减一个数,对定义的类有实际的改变,相当于i=i-1;
Date operator-(int day);
bool operator==(const Date& d);
bool operator>(const Date& d);
bool operator<(const Date& d);
Date& operator++();//前置++
Date operator++(int); //后置++;
Date& operator--();//前置--
Date operator--(int); //后置--;
bool operator >= (const Date& d);
bool operator <= (const Date& d);
bool operator != (const Date& d);
private:
int _year;
int _month;
int _day;
};
然后我们实现函数功能
#include"Date.h"
inline int GetMonthday(int year,int month)//获得当月日期数
{
int dayArr[13]={0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int day=dayArr[month];
if(month==2&&((year%4==0&&year%100!=0)||(year%400==0)))
{
day=29;
}
return day;
}
Date::Date(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 << "非法日期" << endl;
cout << year << "年" << month << "月" << day << "日" << endl;
//assert(false);
//exit(-1);
}
}
Date& Date::operator+=(int day)//日期加等一个数,引用返回,改变类的参数.
{
//思路: *this->day加日期,通过获取当月天数,合法就结束循环,不合法,加月数,直到day合法
if(day<0)
{
*this-=-day;
}
else
{
_day+=day;
//天数不合法,不断进位,让他合法
while(_day>GetMonthday(_year,_month))
{
_day-=GetMonthday(_year,_month);
_month++;
if(_month>12)
{
_year+=_year;
_month=1;
}
}
}
return *this;
}
void Date::Print()//打印日期
{
cout << _year << "年" << _month <<"月"<< _day <<"日"<< endl;
}
Date Date::operator+(int day)//日期加一个数,看下一个日期时什么时候
{
Date ret(*this);//用this构造一个新对象
ret+=day;
return ret;
}
Date& Date::operator-=(int day) //日期减一个数
{
//思路,通过减day,得到一个负数,如果这个数小于0,减月份,如果月份等于0
//year减一,月份置12,再把_day加上每个月份,循环,直到_day大于0
if(day<0)
{
*this+=-day;
}
else
{
_day-=day;
while(_day<=0)
{
--_month;
if(_month==0)
{
_year--;
_month=12;
}
_day+=GetMonthday(_year,_month);
}
}
return *this;
}
Date Date::operator-(int day)
{
Date ret(*this);//构造ret类
ret-=day; //复用(-=),
return ret; //返回当前值,不改变已经构建好的类
}
bool Date::operator==(const Date& d)
{
return _year==d._year&&
_month==d._month
&&_day==d._day;
}
bool Date::operator>(const Date& d)//两个类比较大小
{
if(_year>d._year)
{
return true;
}
else if(_year==d._year)
{
if(_month>d._month)
{
return true;
}
else if(_month==d._month)
{
if(_day>d._day)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
else
{
return false;
}
}
bool Date::operator<(const Date& d)
{
return !(*this>d);
}
// ++d -> d.operator++(&d)
Date& Date::operator++()
{
*this += 1;
return *this;
}
//后置++//d++
// d++ -> d.operator++(&d, 0)
// int参数不需要给实参,因为没用,他的作用是为了跟前置++构成函数重载
Date Date::operator++(int)
{
Date tmp(*this);
*this+=1;
return tmp;
}
//前置--,
Date& Date::operator--()
{
*this-=1;
return *this;
}
//后置--
Date Date::operator--(int)
{
Date tmp(*this);
*this-=1;
return tmp;
}
bool Date:: operator >= (const Date& d)
{
return (*this==d)||(*this>d);
}
bool Date::operator <= (const Date& d)
{
return (*this==d)||(*this<d);
}
bool Date::operator != (const Date& d)
{
return !(*this==d);
}
再一个测试模块:
#include"Date.h"
void test()
{
Date d1(2021, 5, 25);
d1.Print();
d1 += 50;
d1.Print();
// Date d2 = d1 + 100;//相当于i+10
// d2.Print();
// d1-=50;
// d1.Print();
Date d2 = d1 - 100;//相当于i+10
d2.Print();
cout<<(d1 == d2)<<endl;
cout<<(d1 > d2)<<endl;
cout<<(d1 < d2)<<endl;
++d1;
d1.Print();
d1++;
d1.Print();
--d1;
d1.Print();
d1--;
d1.Print();
cout<<(d1!=d2)<<endl;
}
int main()
{
test();
return 0;
}
就可以看到实现了基本功能