C++-第三章-加餐:日期类

目录

第一节:日期类介绍

第二节:日期类实现

        2-1.构造函数和成员变量

        2-2.析构函数

        2-3.赋值重载运算符

        2-4.得到某个月的天数

        2-5.日期+=天数

        2-6.日期+天数

        2-7.日期-=天数

        2-8.日期-天数

        2-9.前置++

        2-10.后置++

        2-11.前置--

        2-12.后置--

        2-13.各种运算符重载

        2-14.日期-日期

        2-15.流插入重载

        2-16.流提取重载

第三节:完整代码

下期预告:


第一节:日期类介绍

        这次我们将写一个属于自己的日期类,它能够对日期进行一些操作,比如日期-日期得到日期的时间间隔,日期-天数,日期+天数等......下面我们来一一实现。

第二节:日期类实现

        2-1.构造函数和成员变量

namespace LUC
{
	class Date
	{
	public:
		// 全缺省构造
		Date(int year = 1900, int month = 1, int day = 1):
			_year(year),
			_month(month),
			_day(day)
		{}
		// 拷贝构造
		Date(const Date& d)
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}
	private: // 保存日期的成员变量
		int _year;
		int _month;
		int _day;
	};
};

        2-2.析构函数

        因为日期类的成员变量都是内置类型,所以不需要显示的写出析构函数。

        2-3.赋值重载运算符

// 赋值重载运算符
Date& operator=(const Date& d)
{
	_year = d._year;
	_month = d._month;
	_day = d._day;
	return *this;
}

        2-4.得到某个月的天数

        这个函数是为了在对日期进行加减操作时得到正确的年、月、日,我们不会直接调用它,而是在进行加减操作时间接调用它,所以可以把它设置成private函数。

// 得到某年某月的天数
int GetMonthDays(int year,int month)
{
	int monthsDays[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
	if (month == 2 && (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))) // 判断是不是闰月
		return 29;
	return monthsDays[month];
}

        2-5.日期+=天数

        得到当前日期之后x天的日期:

// 日期+=天数
Date& operator+=(int days)
{
	int Days = days + _day; // 得到总的天数
	while (Days > GetMonthDays(_year, _month)) // 只要月份需要进1就一直循环
	{
		Days -= GetMonthDays(_year, _month); // 减去当月天数
		_month+=1; // 月份进1
		if (_month > 12) // 年份进1
		{
			_year += 1;
			_month = 1;
		}
	}
	_day = Days;
	return *this;
}

        2-6.日期+天数

        日期+天数得到一个临时类存储结果,调用的类不修改:

// 日期+天数
Date operator+(int days)
{
	Date tmp(*this); // 创建一个临时类
	tmp += days; // 复用日期+=天数
	return tmp;
}

        2-7.日期-=天数

        我们可以把每个月的天数和_day相加,直到它大于days为止:

// 日期-=天数
Date operator-=(int days)
{
	int Day = _day;
	while (days >= Day)
	{
		_month -= 1;
		if (_month < 1)
		{
			_year--;
			_month = 12;
		}
		Day += GetMonthDays(_year, _month);
	}
	_day = Day - days;
	return *this;
}

        2-8.日期-天数

        它也可以复用日期-=天数:

// 日期-天数
Date operator-(int days)
{
	Date tmp(*this);
	tmp -= days;
	return tmp;
}

        2-9.前置++

        前置++就是先加1天再使用,所以可以直接复用+=:

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

        2-10.后置++

        后置++是先使用后加1天:

        它会报错,这是因为前置++和它不能构成重载(参数相同),可以设置一个参数,但是我们并不使用它:

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

        2-11.前置--

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

        2-12.后置--

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

        2-13.各种运算符重载

// ==重载
bool operator==(const Date& d)
{
	if (_year == d._year && _month == d._month && _day == d._day)
		return true;
	return false;
}
// >重载
bool operator > (const Date& d)
{
	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 operator < (const Date& d)
{
	return !(*this == d || *this > d);
}
// >= 重载 可复用==和>
bool operator >=(const Date& d)
{
	return *this == d || *this > d;
}
// <= 重载 可复用>
bool operator <=(const Date& d)
{
	return !(*this > d);
}

        2-14.日期-日期

        日期-日期得到间隔的天数,首先我们需要写一个函数得到某一年的天数:

// 得到某年的天数
int GetYearDays(int year)
{
	if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))// 判断闰年
	{
		return 356;
	}
	return 355;
}

        然后才能写日期-日期的功能函数:

// 日期-日期
int operator-(const Date& d)
{
	int days = _day;
	int year = _year;
	int month = _month;
	while (year > d._year)
	{
		year--;
		days += GetYearDays(year);
	}
	while (month > d._month)
	{	
		month--;
		days += GetMonthDays(year, month);
	}
	while (month < d._month)
	{
		days -= GetMonthDays(year,month);
		month++;
	}
	return days - d._day;
}

        2-15.流插入重载

        流插入重载用来向文件插入数据:

// <<重载
std::iostream& operator<<(std::iostream& stream)
{
	stream << _year << "-" << _month << "-" << _day;
	return stream;
}

        但是当我们调用时会报错:

 

        这是因为对于两个操作数的运算符来说,左操作数会作为第一个参数,右边会作为第二个参数,而第一个参数是this指针,所以会造成参数类型匹配。

        解决办法,使用友元函数,友元函数不属于这个类,但是可以直接访问类的私有成员,它在类中声明,在类外定义:

// <<重载
friend std::ostream& operator<<(std::ostream& stream, const Date& d);

std::ostream& operator<<(std::ostream& stream, const Date& d)
{
	stream << d._year << "-" << d._month << "-" << d._day;
	return stream;
}

        2-16.流提取重载

        流提取同理,也要使用友元函数:

// >>重载
friend std::istream& operator>>(std::istream& stream, Date& d);

std::istream& operator>>(std::istream& stream,Date& d)
{
	stream >> d._year >> d._month >> d._day;
	return stream;
}

第三节:完整代码

        至此,完整代码如下,可以自己做一下测试:

#include <iostream>
namespace LUC
{
	class Date
	{
	private:
		// 得到某年某月的天数
		int GetMonthDays(int year,int month)
		{
			int monthsDays[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
			if (month == 2 && (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))) // 判断是不是闰月
				return 29;
			return monthsDays[month];
		}
		// 得到某年的天数
		int GetYearDays(int year)
		{
			if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))// 判断闰年
			{
				return 366;
			}
			return 365;
		}
	public:
		// 全缺省构造
		Date(int year = 1900, int month = 1, int day = 1):
			_year(year),
			_month(month),
			_day(day)
		{}
		// 拷贝构造
		Date(const Date& d)
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}
		// 赋值重载运算符
		Date& operator=(const Date& d)
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
			return *this;
		}
		// 日期+=天数
		Date& operator+=(int days)
		{
			int Days = days + _day; // 得到总的天数
			while (Days > GetMonthDays(_year, _month)) // 只要月份需要进1就一直循环
			{
				Days -= GetMonthDays(_year, _month); // 减去当月天数
				_month+=1; // 月份进1
				if (_month > 12) // 年份进1
				{
					_year += 1;
					_month = 1;
				}
			}
			_day = Days;
			return *this;
		}
		// 日期+天数
		Date operator+(int days)
		{
			Date tmp(*this); // 创建一个临时类
			tmp += days; // 复用日期+=天数
			return tmp;
		}
		// 日期-=天数
		Date& operator-=(int days)
		{
			int Day = _day;
			while (days >= Day)
			{
				_month -= 1;
				if (_month < 1)
				{
					_year--;
					_month = 12;
				}
				Day += GetMonthDays(_year, _month);
			}
			_day = Day - days;
			return *this;
		}
		// 日期-天数
		Date operator-(int days)
		{
			Date tmp(*this);
			tmp -= days;
			return tmp;
		}
		// 前置++
		Date& operator++()
		{
			return *this += 1;
		}
		// 后置++
		Date operator++(int)
		{
			Date tmp(*this);
			*this += 1;
			return tmp;
		}
		// 前置--
		Date& operator--()
		{
			return *this -= 1;
		}
		// 后置--
		Date operator--(int)
		{
			Date tmp(*this);
			*this -= 1;
			return tmp;
		}
		// ==重载
		bool operator==(const Date& d)
		{
			if (_year == d._year && _month == d._month && _day == d._day)
				return true;
			return false;
		}
		// >重载
		bool operator > (const Date& d)
		{
			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 operator < (const Date& d)
		{
			return !(*this == d || *this > d);
		}
		// >= 重载 可复用==和>
		bool operator >=(const Date& d)
		{
			return *this == d || *this > d;
		}
		// <= 重载 可复用>
		bool operator <=(const Date& d)
		{
			return !(*this > d);
		}
		// 日期-日期
		int operator-(const Date& d)
		{
			int days = _day;
			int year = _year;
			int month = _month;
			while (year > d._year)
			{
				year--;
				days += GetYearDays(year);
			}
			while (month > d._month)
			{	
				month--;
				days += GetMonthDays(year, month);
			}
			while (month < d._month)
			{
				days -= GetMonthDays(year,month);
				month++;
			}
			return days - d._day;
		}
		// <<重载
		friend std::ostream& operator<<(std::ostream& stream, const Date& d);
		// >>重载
		friend std::istream& operator>>(std::istream& stream, Date& d);
	private: // 保存日期的成员变量
		int _year;
		int _month;
		int _day;
	};
    // 友元函数的实现
	std::ostream& operator<<(std::ostream& stream, const Date& d)
	{
		stream << d._year << "-" << d._month << "-" << d._day;
		return stream;
	}
	std::istream& operator>>(std::istream& stream,Date& d)
	{
		stream >> d._year >> d._month >> d._day;
		return stream;
	}
};

下期预告:

        下次补充类和对象的内容:

        1、友元函数与友元类

        2、 匿名对象

        3、编译器优化

        4、new开辟栈空间

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值