首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >日期类的实现

日期类的实现

作者头像
我不是呆头
发布2025-12-20 10:21:17
发布2025-12-20 10:21:17
1220
举报

构造函数

在学习了C++的6个默认成员函数后,我们现在动手实现一个完整的日期类,来加强对这6个默认成员函数的认识。  这是日期类中所包含的成员函数和成员变量:

代码语言:javascript
复制
// 获取某年某月的天数
inline int GetMonthDay(int year, int month)
{
	// 数组存储平年每个月的天数
	static int dayArray[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
	int day = dayArray[month];
	if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
	{
		//闰年2月的天数
		day = 29;
	}
	return day;
}
// 构造函数
Date::Date(int year, int month, int day)
{
	// 检查日期的合法性
	if (year >= 0
	&& month >= 1 && month <= 12
	&& day >= 1 && day <= GetMonthDay(year, month))
	{
		_year = year;
		_month = month;
		_day = day;
	}
	else
	{
		// 严格来说抛异常更好
		cout << "非法日期" << endl;
		cout << year << "年" << month << "月" << day << "日" << endl;
	}
}

打印函数

代码语言:javascript
复制
void Date::Print()
{
	cout << _year << "/" << _month << "/" << _day << endl;
}

日期 += 天数

对于**+=**运算符,我们先将需要加的天数加到日上面,然后判断日期是否合法,若不合法,则通过不断调整,直到日期合法为止。 调整日期的思路:

  1. 若日已满,则日减去当前月的天数,月加一。
  2. 若月已满,则将年加一,月置为1。

反复执行1和2,直到日期合法为止。

如图:

代码语言:javascript
复制
// 日期 += 天数
	Date& Date::operator +=(int day)
{
	if (day<0)
		{
			// 复用operator-=
			*this -= -day;
		}
	else
	{
		_day += day;
		// 日期不合法,通过不断调整,直到最后日期合法为止
		while (_day > GetMonthDay(_year, _month))
		{
			_day -= GetMonthDay(_year, _month);
			++_month;
			if (_month > 12)
			{
				_year++;
				_month = 1;
			}
		}
	}
	return *this;
}

日期 + 天数

+运算符的重载,要注意:虽然我们返回的是加了之后的值,但是对象本身的值并没有改变。就像a = b + 1,b + 1的返回值是b + 1,但是b的值并没有改变。所以我们可以用this指针指向的对象。

代码语言:javascript
复制
// 日期 + 天数
	Date Date::operator +(int day)
	{
		Date tmp(*this);
		tmp += day;
		while (_day > GetMonthDay(_year, _month))
		{
			_day -= GetMonthDay(_year, _month);
			++_month;
			if (_month > 12)
			{
				_year++;
				_month = 1;
			}
		}
		return tmp;
	}

但是日期 + 天数 的函数可能会觉得冗余,我们可以直接采用复用,且用const对该函数进行修饰,防止函数内部改变了this指针指向的对象。如下:

代码语言:javascript
复制
// 日期 + 天数
	Date Date::operator +(int day)const
	{
		Date tmp(*this);
		tmp += day;
		return tmp;
	}

注意:+=运算符的重载函数采用的是引用返回,因为出了函数作用域,this指针指向的对象没有被销毁。但+运算符的重载函数的返回值只能是传值返回,因为出了函数作用域,对象tmp就被销毁了,不能使用引用返回。

日期 -= 天数

对于-=运算符,我们先用日减去需要减的天数,然后判断日期是否合法,若不合法,则通过不断调整,直到日期合法为止。 调整日期的思路:

  1. 若日为负数,则月减一。
  2. 若月为0,则年减一,月置为12。
  3. 日加上当前月的天数。

反复执行1、2和3,直到日期合法为止。

代码语言:javascript
复制
// 日期 -= 天数
	Date& Date::operator -=(int day)
	{
		if (day < 0)
		{
			// 复用operator+=
			*this += -day;
		}
		else
		{
			_day -= day;
			while (_day <= 0)
			{
				_day += GetMonthDay(_year, _month);
				--_month;
				if (_month == 0)
				{
					--_year;
					_month = 12;
				}
			}
		}
		return *this;
	}

日期 - 天数

和+运算符的重载类似,我们可以复用上面已经实现的-=运算符的重载函数,而且最好用const对该函数进行修饰,防止函数内部改变了this指针指向的对象。

代码语言:javascript
复制
// 日期 - 天数
	Date Date::operator -(int day)const
	{
		Date tmp(*this);
		tmp -= day;
		return tmp;
	}

注意:-=运算符的重载函数采用的是引用返回,但-运算符的重载函数的返回值只能是传值返回,也是由于-运算符重载函数中的tmp对象出了函数作用域被销毁了,所以不能使用引用返回。

前置 ++

代码语言:javascript
复制
// 前置++
Date& Date::operator++()
{
	// 复用operator+=
	*this += 1;
	return *this;
}

后置 ++

代码语言:javascript
复制
// 后置++
Date Date::operator++(int)
{
	Date tmp(*this);// 拷贝构造tmp,用于返回
	// 复用operator+=
	*this += 1;
	return tmp;
}

注意: 后置++也是需要返回加了之前的值,只能先用对象tmp保存之前的值,然后再然对象加一,最后返回tmp对象。由于tmp对象出了该函数作用域就被销毁了,所以后置++只能使用传值返回,而前置++可以使用引用返回。

在这里插入图片描述
在这里插入图片描述

前置 - -

代码语言:javascript
复制
// 前置--
Date& Date::operator--()
{
	// 复用operator-=
	*this -= 1;
	return *this;
}

后置 - -

代码语言:javascript
复制
// 后置--
Date Date::operator--(int)
{
	Date tmp(*this);// 拷贝构造tmp,用于返回
	// 复用operator-=
	*this -= 1;
	return tmp;
}
在这里插入图片描述
在这里插入图片描述

日期类的大小比较关系

日期类的大小关系比较需要重载的运算符看起来有6个,实际上我们只用实现两个就可以了,然后其他的通过复用这两个就可以实现。

注意: 进行日期的大小比较,我们并不会改变传入对象的值,所以这6个运算符重载函数都应该被const所修饰。

> 运算符的重载

运算符的重载很简单,先判断年是否大于,再判断月是否大于,最后判断日是否大于,这其中有一者为真则函数返回true,否则返回false。

代码语言:javascript
复制
bool Date::operator>(const Date& d) const
{
	if (_year > d._year)
	{
		return true;
	}
	else if (_year == d._year)
	{
		if (_month > d._month)
		{
			return true;
		}
		else if (_month == d._month)
		{
			if (_day > d._day)
			{
				return true;
			}
		}
	}
	return false;
}

== 运算符的重载

==运算符的重载也是很简单,年月日均相等,则为真。

代码语言:javascript
复制
bool Date::operator==(const Date& d) const
{
	return _year == d._year
		&&_month == d._month
		&&_day == d._day;
}

>= 运算符的重载

即大于或者等于,满足其中之一即可。

代码语言:javascript
复制
bool Date::operator>=(const Date& d) const
{
	return *this > d || *this == d;
}

< 运算符的重载

<,大于等于的反面即是小于。

代码语言:javascript
复制
bool Date::operator<(const Date& d) const
{
	return !(*this >= d);
}

<= 运算符的重载

<=,大于的返回即是小于等于。

代码语言:javascript
复制
bool Date::operator<=(const Date& d) const
{
	return !(*this > d);
}

!= 运算符的重载

!=,等于的反面即是不等于。

代码语言:javascript
复制
bool Date::operator!=(const Date& d) const
{
	return !(*this == d);
}

日期-日期

日期 - 日期,即计算传入的两个日期相差的天数。我们只需要让较小的日期的天数一直加一,直到最后和较大的日期相等即可,这个过程中较小日期所加的总天数便是这两个日期之间差值的绝对值。若是第一个日期大于第二个日期,则返回这个差值的正值,若第一个日期小于第二个日期,则返回这个差值的负值。

代码语言:javascript
复制
// 日期-日期
int Date::operator-(const Date& d) const
{
	Date max = *this;// 假设第一个日期较大
	Date min = d;// 假设第二个日期较小
	int flag = 1;// 此时结果应该为正值
	if (*this < d)
	{
		// 假设错误,更正
		max = d;
		min = *this;
		flag = -1;// 此时结果应该为负值
	}
	int n = 0;// 记录所加的总天数
	while (min != max)
	{
		min++;// 较小的日期++
		n++;// 总天数++
	}
	return n*flag;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-08-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 构造函数
  • 打印函数
  • 日期 += 天数
  • 日期 + 天数
  • 日期 -= 天数
  • 日期 - 天数
  • 前置 ++
  • 后置 ++
  • 前置 - -
  • 后置 - -
  • 日期类的大小比较关系
    • > 运算符的重载
    • == 运算符的重载
    • >= 运算符的重载
    • < 运算符的重载
    • <= 运算符的重载
    • != 运算符的重载
    • 日期-日期
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档