【C++】日期类实现

📅 2026/7/6 15:29:43 👁️ 阅读次数 📝 编程学习
【C++】日期类实现

日期类实现

1、关系运算符重载

>、>=、<、<=、==、!=
如果判断a是否大于b,可以先写判断a小于b和a等于b的函数,其他的复用

主要框架(.h文件)

#pragmaonce#include<assert.h>#include<iostream>using namespace std;class Date{public:// 友元函数声明friend ostream&operator<<(ostream&out,constDate&d);friend istream&operator>>(istream&in,Date&d);intGetMonthDay(intyear,intmonth){assert(month>0&&month<13);staticintmonthDayArray[13]={-1,31,28,31,30,31,30,31,31,30,31,30,31};if(month==2&&((year%4==0&&year%100!=0)||(year%400==0)))return29;elsereturnmonthDayArray[month];}// 只要不改变调用对象的函数都建议加constvoidPrint()const;boolCheckDate();Date(intyear=1,intmonth=1,intday=1);Date&operator+=(intday);Date operator+(intday)const;Date&operator-=(intday);Date operator-(intday)const;// ++d1; -> d1.operatpr++();Date&operator++();//d1++; -> d1.operatpr++(1);Date operator++(int);// --d1;Date&operator--();//d1;Date operator--(int);bool operator==(constDate&d)const;bool operator!=(constDate&d)const;bool operator<(constDate&d)const;bool operator<=(constDate&d)const;bool operator>(constDate&d)const;bool operator>=(constDate&d)const;// 日期-日期 难intoperator-(constDate&d)const;/*ostream& operator<<(ostream& out) { out << _year << "年" << _month << "月" << _day << "日" << endl; return out; }*/Date*operator&(){returnthis;// return nullptr;}constDate*operator&()const{returnthis;// return nullptr;}private:int_year;int_month;int_day;};ostream&operator<<(ostream&out,constDate&d);istream&operator>>(istream&in,Date&d);

1.重载<

bool Date::operator<(constDate&d)const{if(_year<d._year){returntrue;}elseif(_year==d._year){if(_month<d._month){returntrue;}elseif(_month==d._month){return_day<d._day;}}returnfalse;}

2.重载==

bool Date::operator==(constDate&d)const{return_year==d._year&&_month==d._month&&_day==d._day;}

3.重载<=

bool Date::operator<=(constDate&d)const{return*this<d||*this==d;}

4.重载>

bool Date::operator>(constDate&d)const{return!(*this<=d);}

5.重载>=

bool Date::operator>=(constDate&d)const{return!(*this<d);}

6.重载!=

bool Date::operator!=(constDate&d)const{return!(*this==d);}

2、赋值运算符重载

1.获取某个月的天数

重载+和+=时,涉及日期进位,当日期为这个月的最后一天时,再加一天月份要进一位

intGetMonthDay(intyear,intmonth){assert(month>0&&month<13);staticintmonthDayArray[13]={-1,31,28,31,30,31,30,31,31,30,31,30,31};if(month==2&&((year%4==0&&year%100!=0)||(year%400==0)))return29;elsereturnmonthDayArray[month];}
  • 设置一个数组存放每个月的天数,以月份为下标
  • 把数组设置为静态,因为函数会被调用多次,设置成静态,第一次创建之后,一直到程序结束后还在,可以避免函数调用时重复的创建数组
  • 当月份为2时要判断是否是闰年

2.重载+=

用于给出一个已知日期,计算过了若干天后的日期

Date&Date::operator+=(intday)//这里必须是+= d1+100是错误的 d1没改变{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;}

3.重载+

+和+=的方法类似,可以利用+=实现重载+

Date Date::operator+(intday)const{Date tmp=*this;tmp+=day;returntmp;}

4.重载-=

Date&Date::operator-=(intday){if(day<0){return*this+=-day;}_day-=day;while(_day<=0){--_month;if(_month==0){_month=12;_year--;}// 借上⼀个⽉的天数_day+=GetMonthDay(_year,_month);}return*this;//第二种写法//*this=*this-day;//return *this;//拷贝次数多}

5.重载日期-天数

利用-=重载-

Date Date::operator-(intday)const{Date tmp=*this;tmp-=day;returntmp;}

6.重载日期-日期

intDate::operator-(constDate&d)const{Date max=*this;//存放大日期Date min=d;//存放小日期intflag=1;if(*this<d){max=d;min=*this;flag=-1;}//初始化计数器intn=0;while(min!=max){++min;++n;}returnn*flag;}
  • flag为标记符号,默认*this日期≥d日期,结果为正
  • 调用Date类重载的<运算符,判断当前日期(this)是否小于d,若成立,说明d是大日期,*this是小日期,执行大括号内逻辑
  • 把大日期d赋值给max,把小日期*this赋值给min,falg更新符号为-1,最终结果取负,退出if语句
  • 初始化一个计数器,统计从min到max之间的天数差
  • 最终返回值:

若*this≥d:结果为正,flag=1,返回n

若*this<d:结果为负,flag=-1,返回-n

3、重载++、–

1.重载前置++

Date&Date::operator++(){*this+=1;//先把自己加一天return*this;//加完之后的样子}
  • 返回++之后的值

2.重载后置++

Date Date::operator++(int){Datetmp(*this);//保存自己当前的样子*this+=1;//把自己加一天returntmp;//返回保存下来的自己}
  • 返回++之前的值

3.重载前置–

Date&Date::operator--(){*this-=1;return*this;}
  • 返回–之后的值

4.重载后置–

Date Date::operator--(int){Date tmp=*this;*this-=1;returntmp;}
  • 返回–之前的值

4、重载<<、>>

对于自定义类型,编译器不知道如何打印,所以通过<<打印日期类对象

cin是istream类实例化对象,cout是ostream类实例化对象

将<<重载成全局函数

ostream&operator<<(ostream&out,constDate&d){out<<d._year<<"年"<<d._month<<"⽉"<<d._day<<"⽇"<<endl;returnout;}

注意:因为该运算符重载函数写在全局,默认函数内部无法访问日期类的私有成员变量,所以把该函数设置成友元函数

friend ostream&operator<<(ostream&out,constDate&d);

将>>重载成全局函数

istream&operator>>(istream&in,Date&d){cout<<"请依次输入年⽉日:";in>>d._year>>d._month>>d._day;if(!d.CheckDate()){cout<<"⽇期非法"<<endl;}returnin;}

注意:两个参数都不能加const修饰

friend istream&operator>>(istream&in,Date&d);

如果文章中有错误或不足,欢迎大家指正交流。