实现日期类,就是实现其中的几个默认的成员函数以及一些运算符的重载的实现。
使用初始化成员列表初始化年月日,并且对日期的非法性做以判断。
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;
}
代码如下;
== / !=
//==和!=运算符重载主要实现了判断两个日期是否相等。
//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;
}
运算符的重载看起来很多,但是我们实现起来如果注重一下实现的顺序,就会发现实现的运算符只有几个,其余的运算符的重载可以依赖于其中某几个的实现。