目录
一.运算符重载实现各个接口
1.小于 (d1<d2)
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;
}
}
}
return false;
}
2.等于 (d1=d2)
bool Date::operator==(const Date& d)
{
return _year == d._year
&& _month == d._month
&& _day == d._day;
}
3.小于等于(d1<=d2)
由于已经实现了小于和等于的接口,接下来我们直接复用让代码更加简洁。
bool Date::operator<=(const Date& d)
{
return *this < d || *this == d;
}
4.大于(d1>d2)
bool Date::operator>(const Date& d)
{
return !(*this <= d);
}
5.大于等于(d1>=d2)
bool Date::operator>=(const Date& d)
{
return !(*this < d);
}
6.不等于(d1!=d2)
bool Date::operator!=(const Date& d)
{
return !(*this == d);
}
7.日期+=天数
- 计算方式
(1) 算该年的每个月的天数
//不进行声明和定义分离,本质就是inline(这个函数在后面会被频繁调用)
int GetMonthDay(int year, int month)
{
assert(month > 0 && month < 13);
static int monthDays[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//由于函数要被频繁调用,写成静态就不用频繁的创建数组了
if ( month == 2&&(year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
{
return 29;
}
return monthDays[month];
}
(2)日期+=天数 函数
//d1 += 10
Date& Date:: operator+=(int day)
{
_day += day;
while (_day > GetMonthDay(_year, _month))
{
_day -= GetMonthDay(_year, _month);
++_month;
if (_month == 13)
{
++_year;
_month = 1;
}
}
return *this;
}
8.日期+天数
(1)拷贝构造形式
//d1+10
Date Date:: operator+(int day)
{
Date tmp(*this);//这里*this就是d1----(拷贝构造)
tmp._day += day;
while (_day > GetMonthDay(tmp._year, tmp. _month))
{
tmp._day -= GetMonthDay(tmp._year, tmp._month);
++tmp._month;
if (tmp._month == 13)
{
++tmp._year;
tmp._month = 1;
}
}
return tmp;
}
(2)复用形式
Date Date:: operator+(int day)
{
Date tmp = *this;//拷贝构造
tmp += day;
return tmp;
9.日期-=天数
- 计算方式
//日期-=天数
Date& Date::operator-=(int day)
{
_day -= _day;
while (_day <= 0)
{
--_month;
if (_month == 0)
{
--_year;
_month = 12;
}
_day += GetMonthDay(_year, _month);
}
return *this;
}
10.日期-天数
Date Date::operator-(int day)
{
Date tmp = *this;
tmp = day;
return tmp;
}
11.实现operator++函数
(1)前置++
//++d->d.operator++()
Date & Date::operator++()
{
*this += 1;
return *this;
}
(2)后置++
//为了和前置++区分,强制增加了一个int形参,构成重载区分
// d++ ->d.operator++(0)
Date Date::operator++(int)
{
Date tmp = *this;
*this += 1;
return tmp;
}
12.日期-日期
//日期-日期 d1-d2
int Date::operator-(const Date & d)
{
int flag = 1;
Date max = *this;
Date min = d;
if (*this < d)
{
int flag = -1;
max = d;
min = *this;
}
int n = 0;
while (min != max)
{
++min;
++n;
}
return n * flag;
}
13.流插入运算符重载
由于 << 只支持内置类型,所以我们需要自己写一个函数来支持自定义类型的流插入。
ostream& operator<<(ostream& cout, const Date& d)
{
cout << d._year << "年" << d._month << "月" << d._day << "日" << endl;
return cout;
}
operator<<(cout, d1);
cout << d1 << d2;
- 注意
- 该函数不能写成成员函数,只能放在全局。因为操作符左右两侧操作数的类型不匹配。
- 该函数不能放在Date.h文件中。因为要在两个.cpp文件中包含Date.h头文件,产生定义冲突,解决方法有两个:第一,采用内联的形式;第二,采用声明和定义分离。
14.流提取操作符重载
//流提取
istream& operator>>(istream& in, Date& d)
{
cout << "请依次输入年、月、日";
in >> d._year >> d._month >> d._day;
return in;
}
int main()
{
cin >> d2 >> d1;
cout << d2 << d1;
}
15.检查函数(防止日期错误)
bool Date::CheckInvalid()
{
if (_year <= 0
||_month<1||_month>12
||_day<1||_day>GetMonthDay(_year,_month))
{
return false;
}
else
{
return true;
}
}
- 流提取改进
//流提取
istream& operator>>(istream& in, Date& d)
{
while (1)
{
cout << "请依次输入年、月、日: ";
in >> d._year >> d._month >> d._day;
if (!d.CheckInvalid())
{
cout << "输入了非法日期,请重新输入" << endl;
}
else
{
break;
}
}
return in;
}