目錄
一.運算符重載實現各個接口
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;
}