目录
一、基本功能
1.判断是否为闰年
2.日期加(减)天数
3.日期自增(自减)
4.日期减日期
二、代码实现
1.函数的声明:
#include<assert.h>
#include<iostream>
using namespace std;
class Data
{
friend ostream& operator<<(ostream& out, Data& d);
friend istream& operator>>(istream& in, Data& d);
public:
//是否为闰年
bool LeapYear(int year);
//获取某年某月的天数
int GetMonthDay(int year, int month);
//全缺省构造函数
Data(int year = 2022, int month = 9, int day = 1);
//拷贝构造函数
//Data(const Data& d);
//赋值运算符重载
Data operator=(const Data& d);
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;
//日期+=天数
Data& operator+=(int day);
//日期+天数
Data operator+(int day) const;
//日期-天数
Data operator-(int day)const;
//日期-=天数
Data& operator-=(int day);
//前置++
Data& operator++();
//后置++
Data operator++(int);
//后置--
Data operator--(int);
//前置--
Data operator--();
//日期-日期
int operator-(const Data& d);
//打印
void print()const
{
cout << _year << '-' << _month << '-' << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
2.函数的定义
#include"Data.h"
//是否为闰年
bool Data::LeapYear(int year)
{
return (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0));
}
//获取某年某月的天数
int Data::GetMonthDay(int year, int month)
{
//数组大小最好开13,方便映射,很多成员函数都会用到,所以加上static
static int daysarr[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
if (month == 2 && LeapYear(year))
{
return 29;
}
else
{
return daysarr[month];
}
}
//构造函数
Data::Data(int year = 1 ,int month = 1 , int day = 1)
{
//这里需要加判断,防止输入不合法的日期
if (month > 0 && month < 13
&& day > 0 && day <= GetMonthDay(year, month))
{
_year = year;
_month = month;
_day = day;
}
else
{
cout << "非法日期" << endl;
assert(false);
}
}
//拷贝构造函数 可以不写,编译器会自动完成浅拷贝
//Data:: Data(const Data& d)
// {
// _year = d._year;
// _month = d._month;
// _day = d._day;
// }
//赋值运算符重载 比较日期,建议先写== >(<),比较大小互斥,因此可以复用。
bool Data::operator>(const Data& d)const
{
if (_year > d._year)
return true;
else if (_year == d._year && _month > d._month)
return true;
else if (_year == d._year && _month == d._month && _day > d._day)
return true;
return false;
}
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) ;
}
bool Data::operator<(const Data& d)const
{
return !(*this > d);
}
bool Data::operator<=(const Data& d)const
{
return *this < d || *this == d ;
}
bool Data::operator!=(const Data& d)const
{
return !(*this == d);
}
//赋值运算符重载
Data Data::operator=(const Data& d)
{
//如果this == &d 说明传来的值是一样的,就没必要赋值
if (this != &d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this;
}
//日期+=天数 自身要改变
//加上天数,判断是否比当前月大,如果大,就让_day减去当前月的天数,月加1,如果小,直接返回
//判断月是否超过12月,超过则月份重置为1,年加1。
Data& Data::operator+=(int day)
{
//如果传过来的是个负数,相当于日期减等天数
if (day < 0)
{
*this -= -day;
return *this;
}
_day += day;
while (_day > GetMonthDay(_year, _month))
{
_day -= GetMonthDay(_year, _month);
_month++;
if (_month > 12)
{
_year++;
_month = 1;
}
}
return *this;
}
//日期+天数 自身不变,因此需要拷贝构造一个临时对象。可以直接复用+=
Data Data::operator+(int day)const
{
Data tmp(*this);
tmp+= day;
return tmp;
}
//日期-=天数 自身改变
//减去天数,判断_day是否小于1,大于1直接返回,小于1则让月份减1,_day加上月份对应的天数。
//月份小于1则重置为12,年减1.
Data& Data::operator-=(int day)
{
//如果传的天数是个负数,就等于日期+=天数。
if (day < 0)
{
*this += -day;
return *this;
}
_day -= day;
while (_day < 1)
{
_month--;
if (_month < 1)
{
_month = 12;
_year--;
}
_day += GetMonthDay(_year, _month);
}
return *this;
}
//日期-天数 自身不变,直接复用-=便可
Data Data::operator-(int day)const
{
Data tmp(*this);
tmp._day -= day;
return tmp;
}
//前置++ 返回加1之后的值
Data& Data::operator++()
{
*this += 1;
return *this;
}
//后置++ 返回加1之前的值
Data Data::operator++(int)
{
Data tmp(*this);
*this += 1;
return tmp;
}
//后置-- 返回减1之前的值
Data Data::operator--(int)
{
Data tmp(*this);
*this -= 1;
return tmp;
}
//前置-- 返回减1之后的值
Data Data::operator--()
{
*this -= 1;
return *this;
}
//日期减日期返回天数
//让小的日期循环加1,直到小的日期等于大的日期,就停下来。用一个count统计小的日期加了多少次。
//最终count就是两日期之间的差
int Data::operator-(const Data& d)
{
//假定第一个日期>第二个日期
Data max = *this;
Data min = d;
int flag = 1;
//假定也许会出错,这时交换
if (max < min)
{
max = d;
min = *this;
flag = -1;
}
int count = 0;
while (max != min)
{
++min;//建议用前置++ ,效率更高
count++;
}
return count * flag; //d1-d2,如果d1<d2,flag为-1则为负数,反之为正。
}
ostream& operator<<(ostream& out, Data& d)
{
out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
return out;
}
istream& operator>>(istream& in, Data& d)
{
int year, month, day;
in >> year >> month >> day;
if (month > 0 && month < 13
&& day > 0 && day <= d.GetMonthDay(year, month))
{
d._year = year;
d._month = month;
d._day = day;
}
else
{
cout << "非法日期" << endl;
assert(false);
}
return in;
}