Date类实现
头文件Date.h
#pragma once
#include<iostream>
#include<assert.h>
using namespace std;
class Date
{
public:
Date() {};//无参构造
Date(int year, int month, int day)//构造函数
:_year(year)
, _month(month)
, _day(day)
{
assertDate(*this);//检查是否赋值正确
}
Date(const Date& d)//参数为常量的构造函数
:_year(d._year)
, _month(d._month)
, _day(d._day)
{
assertDate(*this);//检查是否赋值正确
}
//声明中的两个个const 1.const参数在参数括号内 2.const*this在参数括号外
int GetMonthsDays(int _year, int _month);//获取对应年份的对应月有几天
void assertDate(const Date& d);//检查是否赋值正确
friend ostream& operator<<(ostream& out, const Date& d);//以友元的形式 重载<<操作符,实现cout输出Date对象
friend istream& operator>>(istream& in, Date& d);//以友元的形式 重载>>操作符,实现cin输入Date对象
bool operator==(const Date& d)const;//判断两个Date类是否相等
bool operator!=(const Date& d)const;//判断两个Date类是否不相等
bool operator<(const Date& d)const;//判断左值Date是否<右值Date
bool operator>(const Date& d)const;//判断左值Date是否>右值Date
bool operator<=(const Date& d)const;//判断左值Date是否<=右值Date
bool operator>=(const Date& d)const;//判断左值Date是否>=右值Date
Date& operator+=(const int day);//左值Date+=day的+=操作符实现
Date operator +(const int day)const;//左值Date+day的+操作符实现
Date& operator-= (const int day);//左值Date+=day的-=操作符实现
Date operator-(const int day)const;//左值Date-day的-操作符实现
Date& operator++();//左值Date自增形成先自增后使用的前置++操作符的实现
Date operator++(int);//左值Date自增形成先使用后自增的前置++操作符的实现 int参数用于区分前置递增和后置递增运算符重载函数
Date& operator--();//左值Date自增形成先自减后使用的后置--操作符的实现
Date operator--(int);//左值Date自增形成先使用后自减的前置--操作符的实现 int参数用于区分前置递减和后置递减运算符重载函数
int operator-(const Date& d)const;//左值Date-右值Date,计算两个Date类日期的差值的实现
private://封装
int _year;
int _month;
int _day;
};
Date.cpp 其中包含运算符重载的具体实现
#include"Date.h"
int Date::GetMonthsDays(int _year, int _month)//Date:: 是 通过类中的声明 在类外部 定义类中成员函数 的方式
{
int dayArr[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)))//再额外判断是不是闰年
//为什么这么写判断?因为这么些减少不必要的判断消耗。_month判断失败就会退出判断,不需要在判断&&符号后的判断。
{
return 29;
}
else
{
return dayArr[_month];
}
}
void Date::assertDate(const Date& d)
{
if (d._month < 0 || d._month > 13 || d._day<0 ||d._day> GetMonthsDays(d._year, d._month) )
{
cout<<"非法日期类"<<endl;
assert(false);
}
}
ostream& operator<<(ostream& out, const Date& d) //为什么用友元?因为如果不用友元,在类中会自动调用一个*this的指针作为左值参数
//但这里需要的左值参数是out,所以需要使用友元,在类外定义左值参数为out
{
out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
return out;
}
istream& operator>>(istream& in,Date& d)//同<<理
{
in >> d._year >> d._month >> d._day;
return in;
}
bool Date::operator==(const Date& d)const
{
if (_year == d._year && _month == d._month && _day == d._day)
{
return 1;
}
else
{
return 0;
}
}
bool Date::operator!=(const Date& d)const
{
if (_year == d._year && _month == d._month && _day == d._day)
{
return 0;
}
else
{
return 1;
}
}
bool Date::operator<(const Date& d)const
{
if (_year < d._year) { return 1; }
if (_year == d._year && _month < d._month) { return 1; }
if (_year == d._year && _month == d._month && _day < d._day) { return 1; }
else { return 0; }
}
bool Date::operator>(const Date& d)const
{
if (_year > d._year) { return 1; }
if (_year == d._year && _month > d._month) { return 1; }
if (_year == d._year && _month == d._month && _day > d._day) { return 1; }
else { return 0; }
}
bool Date::operator<=(const Date& d)const
{
if (*this < d || *this == d) { return 1; }
else { return 0; }
}
bool Date::operator>=(const Date& d)const
{
if (*this > d || *this == d) { return 1; }
else { return 0; }
}
Date& Date::operator+=(const int day)//为什么先写+=,因为写A+B=C时需要新创建一个C的类返回
//需要创建两次类(1次是函数中的临时对象,1次是传参返回的新对象(具体看下一个函数 +的重载) )
//而+=是引用返回,不需要创建对象
{
_day += day;
while (_day >= GetMonthsDays(_year, _month))
{
_day -= GetMonthsDays(_year, _month);
_month++;
if (_month >= 13)
{
_year++;
_month = 1;
}
}
return *this;
}
/*Date Date::operator+(int day)
{
Date d(*this);//一次创建临时对象
d._day += day;
while (d._day >= GetMonthsDays(d._year,d._month))
{
d._day -= GetMonthsDays(d._year, d._month);
d._month++;
if (d._month >= 13)
{
d._year++;
d._month = 1;
}
}
return d;//返回时创建对象
}
Date& operator+=(int day)
{
*this = *this + day;//复用+就会多创建两次对象
return *this;
}*/
Date Date::operator +(const int day)const
{
Date d(*this);//这里创建一次对象
d += day;//复用+=不需要创建对象
return d;//这里创建一次对象
}
Date& Date::operator-= (const int day)
{
_day -= day;
while (_day <= 0)
{
--_month;
_day += GetMonthsDays(_year, _month);
while (_month <= 0)
{
_year--;
_month = 12;
}
}
return *this;
}
Date Date::operator-(const int day)const
{
Date d(*this);
d -= day;
return d;
}
Date& Date::operator++()
{
*this += 1;
return *this;
}
Date Date::operator++(int)
{
Date d(*this);
*this += 1;
return d;
}
Date& Date::operator--()
{
*this -= 1;
return *this;
}
Date Date::operator--(int)
{
Date d(*this);
*this -= 1;
return d;
}
int Date::operator-(const Date& d)cons
{
Date max = *this;
Date min = d;//假定一个最大值和最小值
int flag = 1;//因为不知道*this大还是d大,所以用flag判断最后的返回正负值
if (*this < d)//判断大小
{
max = d;
min = *this;//修改最大值和最小值
flag = -1;//判断最后返回的正负值
}
int n = 0;//无正负的结果
while (min != max)//使用递归来递归出结果
{
++min;
++n;
}
return n * flag;///无正负的结果*正负号flag
}