【摘要】过去我们因为接触的数据类型比较少,因此不需要对运算符有太多的要求,但是自从我们开始学习C++之后,有了类的概念,如果我们仍想要对类中的对象进行一些操作,那就必须得实现操作符的重载了。
如果我们想要完成关于日期的一些操作,就像简单的加减,日期里面乘除没有意义。还有比如说算两个日期差的天数,用普通的操作符是很难实现的,因此,我们需要重载运算符,使它可以完成日期类的操作。
首先,我们需要分析出一个日期类要完成那些操作?
1.最起码的加减天数然后得到若干天之后或者之前的日期
2.两个日期相减,算出中间差的天数
3.日期的自增和自减
4.比较日期的大小
有了这些基本的需求,我们就可以按步骤取实现我们的日期类了
1.日期类中必须有 年,月,日 三个私有数据,我们可以在类中写出一个构造函数对数据进行显式地初始化。
2.定义需要的成员函数,基本上囊括上述的几种功能。
3.把类中的成员函数声明之后,在类外进行定义。(记得一定要在函数名前面加上类名,我定义的类叫Date,不然函数就没办法调用类中的参数)
4.测试用例,把所有可能出现的情况都进行测试,保证程序可以全部顺利通过。
一点小建议:
因为日期类的实现代码量还是很大的,如果全部写好之后再进行调试有可能会遇到大量的错误,这时候调试起来是相当麻烦,所以读者可以每实现一个函数就进行一次调试,这样可以保证整个工程写完之后没有很多的错误。
下面是实现代码以及测试用例的结果
#include<iostream>
#include<stdlib.h>
#include<assert.h>
using namespace std;
class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1)
:_year(year)
,_month(month)
,_day(day)
{
if(month<1 || month>12 || day<0 || day>GetMonthDay(_year,_month))
{
assert(false);
}
}
Date &operator=(const Date &d);
bool IsInvalid();
bool isLeapYear(int year);
int GetMonthDay(int year, int month);
void Show();
bool operator==(const Date& d); //判断相等
bool operator!=(const Date& d);//判断不等
bool operator>=(const Date& d);//大于等于
bool operator<=(const Date& d);//小于等于
bool operator>(const Date& d); //大于
// d1 < d2
bool operator<(const Date& d); //小于
// d1 + 10
Date operator+(int day);
Date& operator+=(int day);
Date operator-(int day);
Date& operator-=(int day);
int operator-(const Date& d);
//++d1
Date& operator++(); // 前置
//d1++
Date operator++(int); // 后置
Date& operator--(); //前置
Date operator--(int);//后置
private:
int _year;
int _month;
int _day;
};
bool Date::operator==(const Date& d)//判断相等
{
if((_year == d._year)&&(_month ==d._month)&&(_day == d._day))
return true;
else
return false;
}
bool Date:: operator<(const Date&d)//判断小于
{
if ((d._year<_year)
||(d._year==_year&&d._month<_month)
|| (d._year==_year&&d._month==_month&&d._day<_day))
{
return false;
}
return true;
}
bool Date::operator != (const Date & d)//判断不等于
{
return !(*this == d);
}
bool Date:: operator>=(const Date& d)//大于等于调小于的复用
{
return !(*this<d);
}
bool Date::operator<=(const Date& d)//小于等于调用小于和等于的复用
{
return (*this<d || *this == d);
}
bool Date::operator>(const Date& d)//大于调用小于等于的复用
{
return !(*this <= d);
}
int Date::GetMonthDay(int year,int month)//获取当月天数
{
assert(month>0 && month <13);
static int monthday[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int day=monthday[month];
if(month == 2 &&isLeapYear(year))
{
day+=1;
}
return day;
}
//bool Date::IsInvalid()//判断值是否合法
//{
// if((month<0) ||(month>12)||((day<0)||(day>31)
// return false;
//}
bool Date:: isLeapYear(int year)//判断是否是闰年
{
if((year%4==0) && (year %100 !=0 )||(year%400==0))
return true;
else
return false;
}
void Date::Show()
{
cout<<_year<<"/"<<_month<<"/"<<_day<<endl;
}
Date Date:: operator+(int day)//日期加天数
{
if(day<0)
{
return *this-(-day);
}
Date ret(*this);
ret._day+=day;
while(ret._day >GetMonthDay(ret._year,ret._month))
{
ret._day-=GetMonthDay(ret._year,ret._month);
ret._month++;
if(ret._month ==13)
{
ret._year++;
ret._month=1;
}
}
return ret;
}
Date& Date::operator+=(int day)//减少一次拷贝构造
{
*this=*this+day;
return *this;
}
Date Date::operator -(int day)
{
if(day<0)
{
return *this + (-day);
}
Date ret(*this);
ret._day-= day;
while(ret._day<0)
{ ret._month--;
if(ret._month == 0)
{
ret._year--;
ret._month=12;
}
ret._day+=GetMonthDay(ret._year,ret._month);
}
return ret;
}
Date& Date::operator -=(int day)//日期减等
{
return (*this -= day);
}
Date& Date::operator =(const Date &d)
{
if((*this)!=d)
{
this->_year=d._year;
this->_month=d._month;
this->_day=d._day;
}
return (*this);
}
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 day=0;
while(min<=max)
{
min++;
day++;
}
return day*flag;
}
Date& Date::operator ++()
{
*this=*this+1;
return *this;
}
Date Date::operator ++(int)
{
Date tmp(*this);
*this=*this+1;
return tmp;
}
Date& Date::operator --()
{
*this=*this-1;
return (*this);
}
Date Date::operator --(int)
{
Date tmp(*this);
*this=*this-1;
return (tmp);
}
int main()
{
Date d1(2018,5,3);
d1.Show();
Date d2(2018,4,5);
Date d3(2018 ,3,2);
d2.Show();
(d1 + 100).Show();
(d1 +(- 4)).Show();
(d1 - 100).Show();
(d1).Show();
--d1;
d1.Show();
(++d1).Show();
d1=d2=d3;
system("pause");
return 0;
}
结果