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;
}

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


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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/879227.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【LGR-200-Div.4】洛谷入门赛 #27 A - H题解,包含(C++, Go语言)

前言&#xff1a; 本文为【LGR-200-Div.4】洛谷入门赛 #27 A - H题解 我只是一个只会各种暴力法的蒟蒻&#xff0c;这场比赛没有参加&#xff0c;是比赛完去写的&#xff0c;但是那个题目昨天晚上才能提交&#xff0c;导致拖久了一点 最后面贴一个Go语言的&#xff0c;反正也没…

英文ai写作怎么写?5个软件帮助你轻松进行ai写作

英文ai写作怎么写&#xff1f;5个软件帮助你轻松进行ai写作 AI写作工具正在改变内容创作方式&#xff0c;尤其是英文写作。以下是5款优秀的AI写作工具&#xff0c;它们可以帮助你快速、高效地完成各种英文写作任务&#xff0c;无论是博客、文章、社交媒体文案还是电子邮件。 聪…

Internet选项检查所存网页的较新版本的设置

每次访问此页时检查代表着,你无论打开任何网页时,都不用IE缓存,直接刷新浏览每次启动IE时检查,代表着,只要你IE浏览器不关闭,,那么他在访问相当网站,网页时,就会调用IE缓存(你会感觉打开非常快),这时候,他并没有下载网页,,只是调用缓存而已。。但是如果你关闭IE浏览器,再重新打…

AI问答-HTTP:理解 Content-Disposition

本文背景 在下载arraybuffer文件时&#xff0c;想要获取文件名&#xff0c;这时引入本文内容Content-Disposition&#xff0c;我们在Content-Disposition获取到文件名就可以在下载后的文件以该文件名命名了。 一、简介 Content-Disposition是HTTP协议中的一个响应头字段&…

跨平台开发新视角:利用Android WebView实现Web内容的原生体验

在移动应用开发领域&#xff0c;跨平台解决方案一直是一个热门话题。开发者们不断寻求能够同时在iOS和Android平台上提供一致用户体验的方法。而Android的WebView组件&#xff0c;作为一个强大的工具&#xff0c;允许开发者在Android应用中嵌入Web内容&#xff0c;为用户提供接…

第R3/4周:天气预测

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、前言 这周的任务添加了探索式数据分析&#xff08;EDA&#xff09;&#xff0c;什么是探索式数据分析呢&#xff1f; 探索性数据分析&#xff08;Explor…

linux 双网卡服务器突然断电后网卡单通故障解决

某台linux 双网卡服务器突然断电后网卡单通故障解决 故障现象&#xff1a;断电后重启服务器&#xff0c;主用网卡IP只能同网段访问&#xff0c;其他网段无法访问&#xff0c;备用网卡则正常&#xff1b; 解决方案&#xff1a;route -n查询路由信息&#xff0c;发现主网卡路由…

第二期: 第11节, uboot 命令的使用

问题&#xff1a;如果你只想控制一个led 灯&#xff0c;并且不想去写驱动。 那么可以直接 使用uboot 的命令&#xff0c;去改写内存。 uboot 命令的解析&#xff1a; 读命令&#xff0c; md[.b, .w. .l] address 注意&#xff1a; 这里的 .w 指的是两个字节&#xff0c;…

探索Python的Excel世界:openpyxl的魔法之旅

文章目录 探索Python的Excel世界&#xff1a;openpyxl的魔法之旅背景&#xff1a;为什么选择openpyxl&#xff1f;什么是openpyxl&#xff1f;如何安装openpyxl&#xff1f;简单的库函数使用方法场景应用&#xff1a;openpyxl在实际工作中的应用常见bug及解决方案总结 探索Pyth…

Spring高手之路23——AOP触发机制与代理逻辑的执行

文章目录 1. 从整体视角学习Bean是如何被AOP代理的2. AOP代理的触发机制2.1 postProcessAfterInitialization方法源码分析2.2 wrapIfNecessary方法源码分析2.3 时序图演示触发机制 3. AOP代理逻辑的执行3.1 AOP代理如何使用拦截器3.2 proceed方法源码分析3.3 时序图 1. 从整体视…

特价电影票对接接口平台推荐?微客云影票

特价电影票对接接口平台推荐 一、常见的较好平台 微客云影票与全国 12000 多家影院建立了合作&#xff0c;覆盖范围广&#xff0c;其提供的电影票价格普遍低于市场价&#xff0c;平均每张票能省下不少钱&#xff0c;在万达、CGV 等大型影院优惠更为显著。 二、判断平台好坏的…

【Qt】Qt C++ Widget中嵌入qml

1. 效果 2. 方法 使用QQuickWidget方式 QQuickWidget *view new QQuickWidget;view->setSource(QUrl::fromLocalFile("myqmlfile.qml"));view->show();除了QQuickWidget方式还可以使用QQuickView方式&#xff0c;请自行查阅资料 3. 代码 3.1 工程目录 3.2 …

Weblogic部署

要安装weblogic&#xff0c;首先要有java环境&#xff0c;因此需要先安装jdk。 这里需要注意&#xff0c;weblogic版本不同&#xff0c;对应的jdk版本也不同&#xff0c;我在这里就踩了很多坑&#xff0c;我这里下载的是fmw_12.2.1.4.0_wls_lite_generic.jar对应的是jdk-8u333…

visual prompt tuning和visual instruction tuning

visual prompt tuning&#xff1a;作为一种微调手段&#xff0c;其目的是节省参数量&#xff0c;训练时需要优化的参数量小。 输入&#xff1a;视觉信息image token可学习的prompt token 处理任务&#xff1a;比如常见的分类任务 visual prompt tuning visual instruction tu…

唯徳知识产权管理系统 DownloadFileWordTemplate 文件读取漏洞复现

0x01 产品简介 唯徳知识产权管理系统,由深圳市唯德科创信息有限公司精心打造,旨在为企业及代理机构提供全方位、高效、安全的知识产权管理解决方案。该系统集成了专利、商标、版权等知识产权的全面管理功能,并通过云平台实现远程在线办公,提升工作效率。是一款集知识产权申…

客户说了算!精益产品开发,让中小企业精准触达用户需求!——张驰咨询

随着全球经济环境的波动&#xff0c;特别是疫情后经济复苏进程的反复&#xff0c;很多中小制造企业面临产品滞销、同质化严重和内卷竞争加剧的困境。市场饱和、利润微薄&#xff0c;还在新产品开发上遇到了研发人才不足、资金短缺等问题。许多企业在这场市场博弈中徘徊在生死边…

IP协议及相关特性

IP协议负责地址管理和路由选择。它的组成为&#xff1a; 接下来我们将对其中较重要的部分进行介绍。 4位版本&#xff1a;这里的四位版本只有两个取值 分别为IPv4和IPv6&#xff0c;这两个额分别为不同的IP协议&#xff0c;但是现在主流的还是IPv4但是近年来IPv6在中国的普及率…

关于报表新入职及进阶培训入口教程

关于报表新入职及进阶培训入口教程 一、网站二、登陆三、报名入口四、缴费及注意事项1. 报名2. 注意事项 五、学习1.在首页时&#xff0c;可以点个人中心进入学习。2.进入后&#xff0c;可以进入如下步骤。 六、完 一、网站 教育事业统计在线培训 二、登陆 注&#xff1a;如果…

C++速通LeetCode简单第17题-爬楼梯(全网最简单)

思路要点&#xff1a;将问题转化为求斐波那契数列的第n项&#xff0c;然后迭代。 思路分析&#xff1a;最后一次爬的阶数不是1就是2&#xff0c;假设爬n阶的方法数是f(n)&#xff0c;假设最后一次爬1阶&#xff0c;那么爬前面的 n-1阶的方法数是f(n-1)&#xff1b;假设最后一次…

20240911泰山杯初赛--temp

Wireshark打开temp.pcap流量包&#xff0c;发现有很多ICMP协议包。 一些ICMP数据包较大&#xff0c;且可发现&#xff0c;明显在传输HTTP协议数据内容&#xff1a; 右键&#xff0c;【显示分组字节】&#xff0c;进一步分析这些HTTP数据&#xff1a; GET /test.html HTTP/1.…