//在类里声明,类外实现
Date::Date(int year, int month, int day)
{
if (year >= 1 &&
month <= 12 && month >= 1 &&
day >= 1 && day <= GetMonthDay(year, month))
{
_year = year;
_month = month;
_day = day;
}
else
{
cout << "非法日期" << endl;
}
}
//代码小于5行,直接在类里面实现
Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
int Date::GetMonthDay(int year, int month)
{
assert(year >= 0 && month > 0 && month < 13);//断言
const static int monthDayArray[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
//用static修饰数组,将数组放在静态区,不用每次执行判断函数都要开辟这块数组空间,提高效率
//再加一个const,让别人不能修改这个数组里的数据
if (month == 2 && isLeapYear(year))
{
return 29;
}
else
{
return monthDayArray[month];
}
}
// d1 + 100 --> d1.operator+(day);
Date Date::operator+(int day)
{
Date ret(*this);//拷贝构造一个和d1一样的对象,这样就不会改变d1的值
ret._day += day;
while (ret._day > GetMonthDay(ret._year, ret._month))//天数超过该月天数就进1
{
ret._day -= GetMonthDay(ret._year, ret._month);//减去该月天数
ret._month++;
if (ret._month == 13)//如果月超过12,年就进1
{
++ret._year;
ret._month = 1;
}
}
return ret;//返回我们拷贝构造之后的对象
}
Date& operator=(const Date& d)
{
if (this != &d)//判断是不是自己给自己赋值
{
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this;
}
// d1 += 100
Date& Date::operator+=(int day)
{
if (day < 0)//如果加的数是负数
return *this -= -day;//等于调用减等函数
_day += day;
while (_day > GetMonthDay(_year, _month))
{
_day -= GetMonthDay(_year, _month);
_month++;
if (_month == 13)
{
++_year;
_month = 1;
}
}
return *this;
//由于出了加等函数的作用域,*this还没有被销毁,所以我们可以用传引用返回
}
由于加法和加等的逻辑相同,所以我们可以复用加等的代码来实现加法
Date Date::operator+(int day)
{
Date ret(*this);
ret += day;
return ret;
}
// d1 -= 100
Date& Date::operator-=(int day)
{
if (day < 0)//如果减等数是负数
return *this += -day;//等于调用加等函数
_day -= day;
while (_day <= 0)
{
--_month;
if (_month == 0)
{
_month = 12;
--_year;
}
_day += GetMonthDay(_year, _month);
}
return *this;
}
由于减等和减法的逻辑相同,所以我们可以复用减等的代码来实现减法
Date Date::operator-(int day)
{
Date ret = *this;
ret -= day;
return ret;
}
//前置++代码
// ++d1
Date& operator++() // 前置
{
*this += 1;
return *this;//出了作用域*this还在,所以可以用传引用返回
}
后置++
//后置++代码
// d1++
Date operator++(int) //这里不具体接收参数的原因:传参只是为了让编译器判断是不是后置++
{
Date tmp(*this);
*this += 1;
return tmp;//出了作用域tmp就被销毁了,所以只能用传值返回,传值返回就需要拷贝
}
//小于运算符重载
bool Date::operator<(const Date& d)
{
if ((_year < d._year)
|| (_year == d._year && _month < d._month)
|| (_year == d._year && _month == d._month && d._day < d._day))
{
return true;
}
else
{
return false;
}
}
等于运算符重载
// d1 == d2
bool Date::operator==(const Date& d)
{
return _year == d._year
&& _month == d._month
&& _day == d._day;
}
// inline不支持声明和定义分别放到.h 和.cpp
// 所以成员函数中要成为inline最好直接在类里面定义
// 类里面定义默认就是inline
bool operator>(const Date& d)
{
return !(*this <= d);
}
bool operator>=(const Date& d)
{
return !(*this < d);
}
bool operator!=(const Date& d)
{
return !(*this == d);
}
// d1 <= d2
bool operator<=(const Date& d)
{
return *this < d || *this == d;
}
// d1 - d2
int Date::operator-(const Date& d)
{
int flag = 1;
Date max = *this;
Date min = d;
if (*this < d)
{
min = *this;
max = d;
flag = -1;
}
int n = 0;
while (min != max)
{
++n;
++min;
}
return n * flag;
}
//流插入重载
std::ostream& operator<<(std::ostream& out, const Date& d)
{
out << d._year << "_" << d._month << "_" << d.day << endl;
return out;
}
std::istream& operator>>(std::istream& in, Date& d)
//流提取不加const的原因:流插入就是把从流里面提取到的值写入到d里
//如果用了const就只能读不能写
{
in >> d._year >> d._month >> d.day;
return in;
}
friend std::ostream& operator<<(std::ostream out,const Date& d);//流插入
friend std::istream& operator>>(std::istream out,Date& d);//流提取
//void Print(const Date* const this)
void Print() const//相当于上面那行代码
{
cout << _year << "-" << _month << "-" << _day << endl;
}
bool opeartor>(const Date& d) const
{
return true;
}