C++:日期类的实现

目录

一、前言

二、头文件

三、各个函数的实现

打印、检查日期及获取日期

=、+=、-=、-、+

[==、<、<=、>、>=、 !=](#==、<、<=、>、>=、 !=)

日期-日期

>>、<<


一、前言

前面几篇讲了关于类和对象的一些知识,本篇就来实现一下前面用到的日期类。

二、头文件

先写上头文件,明确我们要实现哪些函数,还有一些实现函数需要用到的头文件,在头文件中定义日期类及其类中的函数。

#include<iostream>
using namespace std;
class date

{
	friend ostream& operator<<(ostream& out, const date& d);
	friend istream& operator>>(istream& in, date& d);

public:
	void Print();
	bool CheckDate();

	// 获取某年某月的天数
	int GetMonthDay(int year, int month);

	// 全缺省的构造函数
	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);

	// 日期+=天数
	date& operator+=(int day);

	// 日期+天数
	date operator+(int day);

	// 日期-天数
	date operator-(int day);

	// 日期-=天数
	date& operator-=(int day);

	// 前置++
	date& operator++();

	// 后置++
	date operator++(int);

	// 后置--
	date operator--(int);

	// 前置--
	date& operator--();

	// >运算符重载
	bool operator>(const date& d);

	// ==运算符重载
	bool operator==(const date& d);

	// >=运算符重载
	bool operator >= (const date& d);

	// <运算符重载
	bool operator < (const date& d);

	// <=运算符重载
	bool operator <= (const date& d);

	// !=运算符重载
	bool operator != (const date& d);

	// 日期-日期 返回天数
	int operator-(const date& d);

private:
	int _year;
	int _month;
	int _day;

};
ostream& operator<<(ostream& out, const date& d);
istream& operator>>(istream& in, date& d);

这里写日期类的流输入和流输出用到的是友元函数的方法,如果是写在类里面的话,由于类函数自带的(Date* this),在使用时和我们的流输入流输出的习惯会相反,就像这样

b>>a>>cout

这样的写法就会很别扭,所以这里是用到了友元函数的写法来解决这样的问题。

三、各个函数的实现

打印、检查日期及获取日期

打印就是按照 年/月/日 这种形式来打印,检查日期是用来判断输入的日期是否有误,获取日期后面函数的实现基本都需要用到获取日期的功能,这里作为一个函数实现会方便很多。

void date::Print()
{
	cout<<_year<< "/" << _month <<"/"<< _day << endl;
}

bool date::CheckDate()
{
	if (_month<1 || _month>13 || _day < 0||_day>GetMonthDay(_year,_month))
		return false;
	else
		return true;
}

int date::GetMonthDay(int year, int month)
{
	static int monthday[13] = { -1,31,28,31,30,31,30,31,31,30,31,30,31 };
	if (month == 2 && (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
	{
		return 29;
	}
	else
		return monthday[month];
}

获取日期的函数这里再说一下,monthday数组给了13个元素是为了方便用的时候可以对应到我们的1到12月,第一个元素就随便写一个就行了,用来凑数的。

=、+=、-=、-、+

这几个分别是日期的赋值、日期+=天数、日期+天数、日期-天数、日期-=天数

date& date::operator=(const date& d)
{
	_year = d._year;
	_month = d._month;
	_day = d._day;
	return *this;
}

日期的赋值就是把单个的赋值改成年月日的赋值就行了。

date& date::operator+=(int day)
{
	if (day < 0)
	{
		_day -= -day;
		return *this;
	}
	_day += day;
	while (_day > GetMonthDay(_year, _month))
	{
		_day -= GetMonthDay(_year, _month);
		++_month;
		if (_month == 13)
		{
			_year++;
			_month = 1;
		}
	}
	return *this;
}

前面用到-=的代码是为了解决给的天数为负数的问题,直接转换成-=计算,后面+=的逻辑就是先让年月日中的日的值加上我们给的天数,在进入一个循环,不断地判断日的值是否大于月的最大天数,如果大于就让月数+1,继续循环判断,直到日的值小于该月的最大天数,期间如果月份大于了13就给年份+1,月份从1月重新开始加,最后就会得到加完天数后的月份了。

date& date::operator-=(int day)
{
	if (day < 0)
	{
		_day += -day;
		return *this;
	}
	_day -= day;
	while (_day <= 0)
	{
		_month--;
		if (_month == 0)
		{
			_year++;
			_month = 12;
		}
		_day += GetMonthDay(_year, _month);
	}
	return *this;
}

-=也是类似的,前面避免给的天数为负值的情况,然后直接让日的值减去天数,进入循环,如果日的值为负数就要加上该月的最大天数,月份-1,直到日的值大于0,如过期间月份=0了就年份-1,月份从12月重新开始计算,最后得到日期。

date date::operator+(int day)
{
	date tem = *this;
	tem += day;
	return tem;
}
date date::operator-(int day)
{
	date tem = *this;
	tem -= day;
	return tem;
}

有了前面的-=和+=,写-和+就可以直接套用了。

前置++、后置++、前置--、后置--

在C++中为了区分++和--的前置和后置,后置的--和++是需要带参数的,这里需要注意一下。

date& date::operator++()
{
	*this += 1;
	return *this;
}
date date::operator++(int)
{
	date tem = *this;
	*this += 1;
	return tem;
}
date date::operator--(int)
{
	date tem = *this;
	*this -= 1;
	return tem;
}
date& date::operator--()
{
	*this -= 1;
	return *this;
}

++和--其实和前面的天数+-差不多,其实就是把给的day变成了1,这里也是直接套用前面的-=和+=,这里给的代码看一下,就不过多的解释了。

==、<、<=、>、>=、 !=

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

判断两个日期是否相同比较一下年月日就行了,很简单。

bool date::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;
}

比较两个日期的大小,先比较两个日期的年份,如果相等再比较月份,最后再比较天数就行了,也是比较简单的代码,这里写的<的,也就是左边的日期比右边的日期小就返回true,反之则是false,比较大小的逻辑,<和>是一样的。

bool date::operator <= (const date& d)
{
	return *this<d || *this==d;
}

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

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

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

后面的函数实现就可以套用前面两个函数,小于或者等于就是<=,不<=就是大于,不小于就是>=,否定相等相等就是!=,一环套一环还是挺有意思的不用写那么多代码。

日期-日期

这个函数和前面的-不一样,前面的是日期-天数得到日期,这个是日期-日期得到天数

int date::operator-(const date& d)
{
	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;
}

这个就是先把左边的日期定为大日期,右边的定为小日期,让小日期不断地++,直到和大日期相同为止,用一个变量记录,就可以得到差值,如果是右边的天数大,用到了一个flag的变量,就会返回负值。

>>、<<

ostream& operator<<(ostream& out, const date& d)
{
	out << d._year << "/" << d._month << "/" << d._day<<endl;
	return out;
}

日期类的输出就是直接把对象的年月日输出就行了,这里的out就是cout的引用,返回cout是为了和原本的cout一样能输出多个对象。

istream& operator>>(istream& in, date& d)
{
	cout << "请按年月日依次输入日期:" << endl;
	in >> d._year >> d._month >> d._day;
	if (!d.CheckDate())
	{
		cout << "非法日期,请重新输入" << endl;
		cout << "请按年月日依次输入日期:" << endl;
		in >> d._year >> d._month >> d._day;
	}
	return in;
}

日期类的输入也差不多,就是这里加了一个判断输入的日期是否合法,用到了前面日期检查的函数。


本篇关于日期类的实现就到这里了,实现完后不要忘记了测试一下,好了,希望这篇内容对各位有帮助,如果有错误欢迎指出。

相关推荐
十年一梦实验室6 分钟前
【C++】sophus : sim_details.hpp 实现了矩阵函数 W、其导数,以及其逆 (十七)
开发语言·c++·线性代数·矩阵
taoyong00110 分钟前
代码随想录算法训练营第十一天-239.滑动窗口最大值
c++·算法
最爱番茄味15 分钟前
Python实例之函数基础打卡篇
开发语言·python
这是我5816 分钟前
C++打小怪游戏
c++·其他·游戏·visual studio·小怪·大型·怪物
fpcc24 分钟前
跟我学c++中级篇——C++中的缓存利用
c++·缓存
呆萌很42 分钟前
C++ 集合 list 使用
c++
Oneforlove_twoforjob1 小时前
【Java基础面试题033】Java泛型的作用是什么?
java·开发语言
engchina1 小时前
如何在 Python 中忽略烦人的警告?
开发语言·人工智能·python
向宇it1 小时前
【从零开始入门unity游戏开发之——C#篇24】C#面向对象继承——万物之父(object)、装箱和拆箱、sealed 密封类
java·开发语言·unity·c#·游戏引擎
诚丞成2 小时前
计算世界之安生:C++继承的文水和智慧(上)
开发语言·c++