话说c++和c最重大的不同就是c++有了类这个类型,今天就来封装一个类。
日期类是一种很常用的类,但是c++就是没有封装,只能手动封装了。
涉及到类的构建,一定记住上来先考虑默认成员函数
●构造函数
●拷贝构造
●运算符重载
●析构函数
日期类主要有以下功能。
1. 显示
2. 判断两个日期的关系
3.日期加天数
4.日期减天数
5.日期加等天数
6.日期减等天数
7.日期自加,自减(前置和后置)
8.日期减日期
类的声明如下:
class Date
{
public:
Date(int year = 0, int month = 1, int day = 1);
void Show( );
bool operator==(Date& d);
bool operator!=(Date& d);
bool operator<(Date& d);
bool operator>(Date& d);
bool operator<=(Date& d);
bool operator>=(Date& d);
Date& operator=(const Date& d);
Date operator+(int day);
Date operator-(int day);
Date& operator+=(int day);
Date& operator-=(int day);
Date& operator++();//前置
Date operator++(int);//后置
Date& operator--();//前置
Date operator--(int);//后置
int operator-(Date& d);
private:
int _year;
int _month;
int _day;
};
当类的成员函数比较过多或者很长,最好把声明和定义分开。
成员函数的定义:
//这里单独抽象一个判断闰年的函数,因为后面有多处使用
bool IsLeapYear(int year)
{
if((year % 4 == 0 && year % 100 != 0)
|| (year % 400 == 0))
return true;
return false;
}
//这里抽象一个判断一个月的天数也是同理
int GetMonthDay(int year, int month)
{
assert(month>0 && month<13);
int days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if(month == 2 && IsLeapYear(year))
days[2] = 29;
return days[month];
}
Date::Date(int year, int month, int day)//构造函数
{
assert(month<13 && month>0 && day>0 && day < GetMonthDay(year, month));
_year = year;
_month = month;
_day = day;
}
void Date::Show()//显示
{
std::cout << _year << "-" << _month << "-" << _day << std::endl;
}
bool Date::operator==(Date& d)//判断是否两个日期是否相等
{
return (_year == d._year
&&_month == d._month
&&_day == d._day);
}
bool Date::operator!=(Date& d) //不等于,直接复用等于取反
{
return !(*this == d);
}
bool Date::operator<(Date& d)//两个日期比较大小
{
if(_year<d._year
|| (_year == d._year && _month<d._month)
|| (_year == d._year && _month == d._month && _day<d._day))
return true;
return false;
}
bool Date::operator>(Date& d)//大于(复用小于等于)
{
return !(*this<=d);
}
bool Date::operator<=(Date& d)//小于等于(复用小于和等于)
{
return (*this<d) || (*this == d);
}
bool Date::operator>=(Date& d)//大于等于(复用小于)
{
return !(*this < d);
}
Date& Date::operator=(const Date& d)//赋值运算符
{
if(*this != d)
{
(*this)._year = d._year;
(*this)._month = d._month;
(*this)._day = d._day;
}
return *this;
}
Date Date::operator+(int day)//日期加天数
{
if(day<0)
{
day = -day;
return *this-day;
}
Date ret = *this;
ret._day += day;
while(ret._day>GetMonthDay(ret._year, ret._month))
{
ret._day -= GetMonthDay(ret._year, ret._month);
ret._month++;
if(ret._month == 13)
{
ret._year++;
ret._month = 1;
}
}
return ret;
}
Date Date::operator-(int day)//日期减天数
{
if(day<0)
{
day = -day;
return *this + day;
}
Date ret = *this;
ret._day -= day;
if(ret._day>0)
return ret;
while(ret._day <= 0)
{
ret._month--;
if(ret._month == 0)
{
ret._year--;
ret._month = 12;
}
ret._day += GetMonthDay(ret._year, ret._month);
}
return ret;
}
Date& Date::operator+=(int day)//加等(复用)
{
return (*this = (*this + day));
}
Date& Date::operator-=(int day)//减等(复用)
{
return (*this = (*this - day));
}
Date& Date::operator++()//前置
{
return *this = *this + 1;
}
Date Date::operator++(int)//后置
{
Date ret(*this);
*this = *this + 1;
return ret;
}
Date& Date::operator--()//前置
{
return *this = *this - 1;
}
Date Date::operator--(int)//后置
{
Date ret(*this);
*this = *this - 1;
return ret;
}
int Date::operator-(Date& d)//日期减日期
{
Date Max(*this);
Date Min(d);
if(*this < d)
{
Max = d;
Min = *this;
}
int count = 0;
while(Max != Min)
{
count++;
Min++;
}
return count;
}
●代码中有多处使用复用(复用的可以避免牵一发动全身,代码易写)
●代码中有多处使用引用(引用做参数和引用做返回值)
●代码中有const做参数
这里躺过一个坑必须说出来,少了一个const的坑,看下图
测试代码很简单,就不给出了,有兴趣的可以自行测试,欢迎反馈bug。