boxmoe_header_banner_img

糖画99

文章导读

日期类实现(类和对象)


avatar
mizuki 2026年5月20日 24

1.引言

此篇文章将对日期类进行基本的实现,以加深对类和对象的理解和运用

ps:注意注意,因为这篇的代码过长,如果想看源代码需要点击那个小三角进行查看

2.类的基本成员对象

一个日期要包含年月日,如下:

这里建议在成员对象前加‘ _ ’,以便于区分参数和成员对象

3.日期类的构造函数

  • 1.参数构造
Date(size_t year, size_t month, size_t day)
{
	if (month > 13 || month < 1 || day > Getmonthday(year, month))
	{
		cout << "创建日期错误" << endl;
	}

	_year = year;
	_month = month;
	_day = day;
}
  • 2.拷贝构造
Date(const Date& tmp)
{
	_year = tmp._year;
	_month = tmp._month;
	_day = tmp._day;
}

这里要注意参数的类型,是const+类引用,原因在类和对象(中)这篇文章已经解释过了

  • 3.默认构造函数
Date() = default;

这里是为了可以无参构造一个日期类对象

4.运算符重载

1.++ 和 — 的重载,包括后置
Date& Date::operator++()
{
	_day++;
	if (_day > GetMonthDay(_year, _month))
	{
		_day = 1;
		_month++;
		if (_month > 12)
		{
			_year++;
			_month = 1;
		}
	}
	return *this;
}

Date& Date::operator--()
{
	_day--;
	if (_day == 0)
	{
		_month--;
		if (_month == 0)
		{
			_month = 12;
			_year--;
		}
		_day = GetMonthDay(_year, _month);
	}
	return *this;
}

Date& Date::operator++(int)
{
	Date tmp(*this);
	_day++;
	if (_day > GetMonthDay(_year, _month))
	{
		_day = 1;
		_month++;
		if (_month > 12)
		{
			_year++;
			_month = 1;
		}
	}
	return tmp;
}

Date& Date::operator--(int)
{
	Date tmp(*this);
	_day--;
	if (_day == 0)
	{
		_month--;
		if (_month == 0)
		{
			_month = 12;
			_year--;
		}
		_day = GetMonthDay(_year, _month);
	}
	return tmp;
}

因为前置跟后置的返回不一样,所以在这一点上要特别注意

2.比较运算符的重载
bool Date::operator==(const Date& tmp)const
{
	return _year == tmp._year && _month == tmp._month && _day == tmp._day;
}
bool Date::operator!=(const Date& tmp)const
{
	return !(*this == tmp);
}


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;
}
bool Date::operator<=(const Date& d) const
{
	return *this < d || *this == d;
}
bool Date::operator>(const Date& d) const
{
	return !(*this <= d);
}
bool Date::operator>=(const Date& d) const
{
	return !(*this < d);
}

这里有一个技巧是,先将<和==写出来,那么其他的运算符都可以通过这两个运算符来进行定义

3.<< 和 >> 的重载
ostream& operator<<(ostream& out, const Date& tmp)
{
	out << tmp._year << " " << tmp._month << " " << tmp._day << endl;
	return out;
}

istream& operator>>(istream& in, Date& tmp)
{
	in >> tmp._year >> tmp._month >> tmp._day;
	return in;
}

主要是要注意要将这两个重载函数作为友元函数包含在类中,并且还要注意返回的类型

4.+= + -= – 的重载
// d1 += 天数
Date& Date::operator+=(int day)
{
	//防止为负数
	if (day < 0)
	{
		day = -day;
		return *this -= day;
	}
	_day = _day + day;
	while (_day > Getmonthday(_year, _month))
	{
		_day = _day - Getmonthday(_year, _month);
		_month++;
		if (_month == 13)
		{
			_year++;
			_month = 1;
		}
		
		return *this;
	}
}

Date Date::operator+(int day) const
{
	Date tmp = *this;
    tmp += day;
	return tmp;
}

// d1 -= 天数
Date& Date::operator-=(int day)
{
	if (day < 0)
	{
		day = -day;
		return *this += day;
	}

	_day += day;
	while (_day < 0)
	{
		_day += Getmonthday(_year, _month);
		_month--;
		if (_month < 0)
		{
			_year--;
			_month = 1;
		}
	}

	return *this;
}
Date Date::operator-(int day) const
{
	Date tmp = *this;
	tmp -= day;
	return tmp;
}

这里+= + -= -的都是具体多少天,定义中可以直接用++或者–表示,虽然会增加时间复杂度,但是可以忽略不计,要注意的是,这里天数可能是负数,所以要单独写出这个特例

5.day1 – day2的重载
// d1 - d2
int Date::operator-(const Date& d) const
{
	int n = 0;
	Date day1(*this);
	Date day2(d);
	if (day1 > day2)
	{
		while (day1 != day2)
		{
			day2++;
			n++;
		}
	}
	else
	{
		while (day1 != day2)
		{
			day2--;
			n--;
		}
	}
	return n;
}

这里意在计算两个日期之间相差的天数,也要考虑谁大谁小的问题,要强调的是因为两个日期之间相加是没有意义的,因为这里不需要重载

5.总结

通过重写日期类,你可以从中巩固自己类和对象的知识,但这还是一点皮毛,下一篇文章将继续探讨类和对象的更深层次的东西



评论(0)

查看评论列表

暂无评论


发表评论

表情 颜文字

插入代码
小园得志