第1关:日期类的运算符重载
头文件 date.h
// 头文件保护宏,防止重复包含
#ifndef DATE_CLASS
#define DATE_CLASS
#include <iostream>
using namespace std;
// Date日期类声明
class Date{
// 私有成员:年、月、日
int year,month,day;
// 私有成员函数
bool isLeap()const; // 判断当前年份是否为闰年
int dayInMonth()const; // 获取当前月份的总天数
void normalize(); // 日期标准化:自动修正非法年月日(比如日超过当月天数、月份超出1-12)
public:
// 构造函数:默认参数 年=1,月=1,日=1
Date(int y=1,int m=1,int d=1);
// 关系运算符重载 == < > <= >= !=
bool operator==(const Date& other)const; // 判断两个日期是否相等
bool operator<(const Date& other)const; // 判断当前日期是否早于other日期
bool operator>(const Date& other)const; // 判断当前日期是否晚于other日期
bool operator<=(const Date& other)const; // 判断当前日期是否早于/等于other日期
bool operator>=(const Date& other)const; // 判断当前日期是否晚于/等于other日期
bool operator!=(const Date& other)const; // 判断两个日期是否不相等
// 复合赋值运算符重载:日期增减N天
Date& operator+=(int days); // 当前日期向后推days天,返回自身引用
Date& operator-=(int days); // 当前日期向前推days天,返回自身引用
// 自增运算符重载(日期+1天)
Date& operator++(); // 前置++:++date,先自增再返回自身
Date operator++(int); // 后置++:date++,先返回原值再自增
// 自减运算符重载(日期-1天)
Date& operator--(); // 前置--:--date,先自减再返回自身
Date operator--(int); // 后置--:date--,先返回原值再自减
// 友元运算符重载
friend int operator-(const Date& d1,const Date& d2); // 两个日期相减,返回相差天数(d1-d2)
friend ostream& operator<<(ostream& os,const Date& dt); // 输出流重载 cout << Date对象
friend istream& operator>>(istream& is,Date& dt); // 输入流重载 cin >> Date对象
};
#endif
源文件 date.cpp
#include"date.h"
using namespace std;
// 判断闰年:能被4整除且不能被100整除,或能被400整除
bool Date::isLeap()const{
return (year%4==0&&year%100!=0)||(year%400==0);
}
// 获取当月总天数:2月闰年29天,平年28天;其他月份固定天数
int Date::dayInMonth()const{
int days[]={31,28,31,30,31,30,31,31,30,31,30,31};
if(month==2&&isLeap())return 29;
return days[month-1];
}
// 日期标准化函数:自动修正非法日期
void Date::normalize(){
// 当日数大于当月总天数:进位到下个月
while(day>dayInMonth()){
day-=dayInMonth();
month++;
// 月份超过12,进位到下一年
if(month>12){
month=1;
year++;
}
}
// 当日数小于1:向上个月借天数
while(day<1){
month--;
// 月份小于1,借到上一年12月
if(month<1){
month=12;
year--;
}
day+=dayInMonth();
}
}
// 构造函数:初始化年月日,调用标准化函数修正非法输入
Date::Date(int y,int m,int d):year(y),month(m),day(d){
normalize();
}
// ==重载:年月日全部相等才返回true
bool Date::operator==(const Date& other)const{
return year==other.year&&month==other.month&&day==other.day;
}
// <重载:先比年,年相同比月,月相同比日
bool Date::operator<(const Date& other)const{
if(year!=other.year)return year<other.year;
if(month!=other.month)return month<other.month;
return day<other.day;
}
// >重载:利用<运算符,other早于this等价于this晚于other
bool Date::operator>(const Date& other)const{
return other<*this;
}
// <=重载:取反 > 运算符
bool Date::operator<=(const Date& other)const{
return !(other<*this);
}
// >=重载:取反 < 运算符
bool Date::operator>=(const Date& other)const{
return !(*this<other);
}
// !=重载:取反 == 运算符
bool Date::operator!=(const Date& other)const{
return !(*this==other);
}
// +=重载:日期向后加days天,标准化后返回自身
Date& Date::operator+=(int days){
day+=days;
normalize();
return *this;
}
// -=重载:日期向前减days天,标准化后返回自身
Date& Date::operator-=(int days){
day-=days;
normalize();
return *this;
}
// 前置++:日期+1天,返回自增后的自身
Date& Date::operator++(){
*this+=1;
return *this;
}
// 后置++:先保存当前日期副本,再日期+1天,返回原来的副本
Date Date::operator++(int){
Date temp=*this;
*this+=1;
return temp;
}
// 前置--:日期-1天,返回自减后的自身
Date& Date::operator--(){
*this-=1;
return *this;
}
// 后置--:先保存当前日期副本,再日期-1天,返回原来的副本
Date Date::operator--(int){
Date temp=*this;
*this-=1;
return temp;
}
// 友元-重载:计算两个日期相差天数 d1 - d2
int operator-(const Date& d1,const Date& d2){
Date temp=d2;
int days=0;
// 如果d1更早,temp不断往前减,days记负数
if(d1<d2){
while(temp>d1){
--temp;
days--;
}
return days;
}else{
// 如果d1更晚,temp不断往后加,days记正数
while(temp<d1){
++temp;
days++;
}
return days;
}
}
// 输出流重载:打印格式 年-月-日
ostream& operator<<(ostream& os,const Date& dt){
os<<dt.year<<"-"<<dt.month<<"-"<<dt.day;
return os;
}
// 输入流重载:读取年、月、日,读取后标准化修正
istream& operator>>(istream& is,Date& dt){
is>>dt.year>>dt.month>>dt.day;
dt.normalize();
return is;
}
主函数 main.cpp
#include"date.h"
using namespace std;
int main(){
Date d1,d2;
// 输入两个日期
cin>>d1>>d2;
// d1向后推2天,输出d1
d1+=2;
cout<<d1<<endl;
// d2向前推3天,输出d2
d2-=3;
cout<<d2<<endl;
// 前置++:d1日期+1,输出新d1
++d1;
cout<<d1<<endl;
// 后置++:先输出原值,d2再+1
d2++;
cout<<d2<<endl;
// 判断d1和d2大小,输出相差天数
if(d1==d2){
cout<<0<<endl;
}else if(d1<d2){
cout<<d2-d1<<endl;
}else{
cout<<d1-d2<<endl;
}
// 前置--:d1先-1,把修改后的d1赋值给d3,输出d3
Date d3=--d1;
cout<<d3<<endl;
// 后置--:先把d2原值赋值给d4,d2再-1,输出d4
Date d4=d2--;
cout<<d4<<endl;
// 判断d3和d4大小,输出相差天数
if(d3==d4){
cout<<0<<endl;
}else if(d3<d4){
cout<<d4-d3<<endl;
}else{
cout<<d3-d4<<endl;
}
return 0;
}