编写一个日期类CDate,使得能够设置日期、显示日期、实现前置自增后置自增的重载函数。
该类的框架定义如下:
class CDate
{
private:
int year, month, day; //年月日
static const int days[12]; //定义月份的天数,默认是闰年,用法:day=days[month-1]
public:
CDate(int Y = 2016, int M = 1, int D = 1);//带有默认值的构造函数
~CDate() {} //析构函数
bool set(int Y = 2016, int M = 1, int D = 1); //带有默认值的设置日期函数,如果日期异常,则返回false
static bool is_leap_year(int Year){return ((Year % 4 == 0 && Year % 100 != 0) || (Year % 400 == 0));} //返回是否是闰年
CDate& operator++(); // ++a //前置后置自重载函数实现
CDate operator++(int); //a++
friend ostream& operator<<(ostream& out, const CDate& variable);//定义提取运算符重载
};
其中有几点需要注意:
1.类中常量实现办法
static const int days[12]; //定义月份的天数,默认是闰年,用法:day=days[month-1]
这一个数组是用来保存常量值的,也就是12个月份的天数。要将
其定义为static静态类型的常数组,需要注意
此时不能被初始化,因为类只是一个声明,没有开辟空间。其
初始化要在实现文件中或类外定义方法的文件中实现,
不加static但是要加域名:
const int CDate::days[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
注意此时不要带static。
关于类中定义常量还有以下两个常用方法:
a.)使用枚举类型。如在类中定义:
class CDate
{
public:
enum days={january=31,february=28}//....etc
}
b.)使用指针。在类中定义常量指针,在类外定义常数组,然后在构造函数中将数组地址赋值给指针:
const int Days[12]={31,28,31,30,31,30,31,31,30,31,30,31 };
class CDate
{
public:
CDate(int Y = 2016, int M = 1, int D = 1):days(Days);
private:
const int* const days;
};
类中关于静态变量的定义也是类似:需要在
类外定义且不加static但是要加域名:
class CDate
{
private:
static int how_much;
};
int CDate::how_much=12;
类中关于静态函数同样如此:需要在
类外定义且不加static但是要加域名:
class CDate
{
public:
static bool is_leap_year(int Year);//返回是否是闰年
};
bool CDate::is_leap_year(int Year)
{
return ((Year % 4 == 0 && Year % 100 != 0) || (Year % 400 == 0));
}
2.前置后置自增运算符重载函数
CDate& operator++(); // ++a //前置后置自重载函数实现
CDate operator++(int); //a++
第二个函数中的int是形式上区分标志,无实际意义但是不可缺少。
注意到两个函数的返回值类型不同。第一个前置自增运算符返回的是引用,也就是*this,它将自身自增以后返回它自身。后者返回的是一个临时变量,它先保存原来*this的值,然后*this自增,之后返回这个临时变量,也就是原来的*this。其实现如下:
CDate& CDate::operator++()// ++a
{
int add_year = 0, add_month = 0;
if (day == days[month - 1])
add_month = 1, day = 1;
else
day += 1;
///if month==12, add_month==1 or 0, 13%12==1,12%12==0
month = (add_year = month + add_month)==12? 12:add_year%12;
year += add_year / 12;//or month==11, add_month==1,12%12==0
return *this;//else month = (month + add_month)% 12
}
CDate CDate::operator++(int)//a++
{
CDate temp = *this;
++*this;
return temp;
}
其抽象以后如下:
CDate& CDate::operator++()// ++a
{
//对*this进行操作
//.....<span style="white-space:pre"> </span>
return *this;//返回*this<span style="white-space:pre"> </span>
}
CDate CDate::operator++(int) //a++
{
CDate temp=*this;//保存原来的*this到临时变量
++*this;//*this自增
return temp;//返回原来的*this
}