目录
一.运算符重载实现各个接口
1.小于 (d1)<>
2.等于 (d1=d2)
3.小于等于(d1<=d2)
4.大于(d1>d2)
5.大于等于(d1>=d2)
6.不等于(d1!=d2)
7.日期+=天数
(1) 算该年的每个月的天数
(2)日期+=天数 函数
8.日期+天数
(1)拷贝构造形式
(2)复用形式
9.日期-=天数
10.日期-天数
11.实现operator++函数
(1)前置++
(2)后置++
12.日期-日期
13.流插入运算符重载
14.流提取操作符重载
15.检查函数(防止日期错误)
一.运算符重载实现各个接口
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;
}