c++日期类

接上文来完整实现日期类的成员函数,先是日期类的成员变量

class Date
{
public:

private:
    int _year:
    int _month;
    int _day;
}

在写日期类的默认成员函数和运算符重载之前,我们先写一个函数来获得某年某年某月的具体天数,我们定义一个静态数组monthDayArray[]去记录每个月的天数,如果是闰年的二月就返回二十九天,其他情况下返回monthDayArray[month]

int GetMonthDay(int year, int month)
{
	assert(year >= 0 && month >= 0 && month <= 12);
		
	static int	monthDayArray[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	if (month == 2 && isLeapYear(year))
		return 29;
	else
		return monthDayArray[month];
}

这里面还有一个判断闰年的函数要去实现,这个大家应该都会
 

bool isLeapYear(int year)
{
	return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}

接下来实现日期类的构造函数,也就是把我们输入的年月日赋值给日期对象,需要注意的是我们输入的数据需要是一个有效的日期,我们需要对这个年月日进行检查,年要大于零,月大于零小于等于十二,日大于零小于等于当月最大天数

Date(int year = 1970, int month = 1, int day = 1)
{
	if (year > 0 && (month > 0 && month < 13) && (day > 0 && day <= GetMonthDay(year,month)))
	{
		_year = year;
		_month = month;
		_day = day;
	}
	else
		cout << "非法参数" << endl;
}

拷贝构造就很简单了,对年月日进行赋值即可

Date(const Date& d)
{
	_year = d._year;
	_month = d._month;
	_day = d._day;
}

接下来就是赋值运算符的重载,按照难易顺序来,先来一个==的重载

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

与==相反的是!=,一开始我想的是年不相等或月不相等或日不想等则返回true,但是我们上面已经写了==了,为什么不能把==用起来呢,!=就是==取反,这个思路也让我们下面实现起来更简单

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

接下来我们实现<,按照我们上面的思路,我们实现了<也就间接实现了>=,因为<本就与>=对立,<我的实现思路和我们数学上整型比大小类似,我们可以把日期类的对象看成是一个三位数,先比百位,百位相等就去比十位,以此类推

bool operator<(const Date& d)
{
	if (_year == d._year)
	{
		if (_month == d._month)
		{
			return _day < d._day;
		}
		return _month < d._month;
	}
	else
		return _year < d._year;
}

那>=就是<取反了

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

>和<=和上面类似,我就只贴代码了

bool operator>(const Date& d)
{
	if (_year == d._year)
	{
		if (_month == d._month)
		{
			return _day > d._day;
		}
		return _month > d._month;
	}
	else
		return _year > d._year;
}

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

接下来我们实现+,当然+也有加上多少多少天和加上另一个日期类,我认为日期加日期没有意义,因此就只实现日期加天数,日期加天数是要有返回值的,但是又不能在*this上直接操作,就像是c=a+10;我们的a并不会改变,a不会变成a+10,怎么做呢,我们用拷贝构造创建一个临时对象,在这个临时对象上操作并返回它

至于逻辑实现我们可以把它理解为十进制相加的进位一样,先把天数加到_day里,如果_day大于那个月的天数就进位,月大于十二就进位

Date operator+(int day)
{
	Date temp(*this);
		
	temp._day = temp._day + day;

	while (temp._day > GetMonthDay(temp._year, temp._month))
	{
		temp._day = temp._day - GetMonthDay(temp._year, temp._month);
		temp._month = temp._month + 1;
		if (temp._month > 12)
		{
			temp._month = 1;
			temp._year = temp._year + 1;
		}
	}
	return temp;
}

+=和+的区别就是+=是加在*this上的,返回的是*this

Date operator+(int day)
{
	Date temp(*this);
		
	temp._day = temp._day + day;

	while (temp._day > GetMonthDay(temp._year, temp._month))
	{
		temp._day = temp._day - GetMonthDay(temp._year, temp._month);
		temp._month = temp._month + 1;
		if (temp._month > 12)
		{
			temp._month = 1;
			temp._year = temp._year + 1;
		}
	}
	return temp;
}

-和-=的实现逻辑和上面的类似,也只贴代码了

Date operator-(int day)
{
	Date temp(*this);

	temp._day = temp._day - day;
	while (temp._day <=0)
	{
		temp._month = temp._month - 1;
		if (temp._month == 0)
		{
			temp._month = 12;
			temp._year = temp._year - 1;
		}
		temp._day = temp._day + GetMonthDay(temp._year, temp._month);
	}

	return temp;
}

Date& operator-=(int day)
{
	*this = *this - day;
	return *this;
}

当然还有前后置的自加和自减,有两个问题,一是怎么区分前后置,还有就是前后置的具体实现,如何区别前后置c++已经给了我们解决方案,那就是前置++没有参数,而后置++的参数为(int),那么怎么去实现前置和后置,也就是先自加再运算和先运算再自加,在后置我们可以直接加如何返回,前置只需要对*this进行拷贝,然后*this自加,返回拷贝

Date& operator++()
{
	*this += 1;
	return *this;
}

Date operator++(int)
{
	Date tmp(*this);
	*this += 1;
	return tmp;
}

Date& operator--()
{
	*this -= 1;
	return *this;
}

Date operator--(int)
{
	Date tmp(*this);
	*this -= 1;
	return tmp;
}

Date operator=(const Date& d)
{
	if (this != &d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
	return *this;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值