C++ 日期类的实现

目录

前言

日期类中的成员函数和成员变量 

日期类中成员函数的详解和实现 

1.天数前后的判断

2.天数加减的实现

3.前置++ && 后置++

4.计算天数差值


前言

        日期类的实现将综合前面所学的(类的6个默认成员函数),进一步理解和掌握类的6个默认成员函数。

若对(类的6个成员函数不太理解)请先看前文:

C++ 类与对象(中)-CSDN博客

C++ 类与对象(中)续-CSDN博客


日期类中的成员函数和成员变量 

以下声明都在.h文件中

class Date
{
public:
	//全缺省的构造函数
	Date(int year = 1, int month = 1, int day = 1);
	//运算符重载
	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);

	// 天数的加减
	Date& operator+=(int day);
	Date operator+(int day);

	Date operator-(int day);
	Date& operator-=(int day);

	//前置++ 后置++
	Date& operator++();
	// 特殊处理:解决语法逻辑不自洽,自相矛盾的问题
	// d1++
	// 为了跟前置++区分,强行增加一个int形参,够成重载区分
	Date operator++(int);

	Date operator--(int);
	Date& operator--();

	// 天数-天数
	int operator-(const Date& d);

	// 本质就是inline(不声明和定义分离)
	//判断闰年还是平年
	int GetMonthDay(int year, int month)
	{
		assert(month > 0 && month < 13);
		static int monthDays[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

		// 365   自转  公转  365 5+h
		// 366
		if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
		{
			return 29;
		}

		return monthDays[month];
	}

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

private:
	int _year;
	int _month;
	int _day;
};


日期类中成员函数的详解和实现 

1.天数前后的判断

这是 实现Date 类,对比较运算符 < 的重载定义。它比较两个 Date 对象,如果第一个日期早于第二个日期,则返回 true ,否则返回 false 。

以下是它的工作原理:

1. 它比较两个日期的年份。如果第一个日期的年份小于第二个日期的年份,则返回 true 。

2. 如果年份相等,则比较两个日期的月份。如果第一个日期的月份小于第二个日期的月份,则返回 true 。

3. 如果月份相等,则比较两个日期的天数。如果第一个日期的天数小于第二个日期的天数,则返回 true 。

4. 如果所有比较都为 false,则表示两个日期相等,因此返回 false 。

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

==运算符的实现,== 运算符通过比较 _year 、 _month 和 _day 来实现。如果三个成员变量都相等,则返回 true ,否则返回 false 。

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

<=运算符的实现,在上面我们实现了<和=连个运算符,在实现<=的时候我们就可以调用<和=运算符了。

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

天数前后判断函数的测试:

int main()
{
	Date d1(2024, 2, 3);
	Date d2(2024, 2, 1);
	cout << (d1 > d2) << endl;
	cout << (d1 < d2) << endl;
	cout << (d1 >= d2) << endl;
	cout << (d1 <= d2) << endl;
}


2.天数加减的实现

+=操作的实现,这个函数是 Date 类的成员函数,它将一个给定的天数添加到日期中。

它首先将给定的天数添加到 _day 中。然后,它检查 _day 是否大于该月的总天数。如果大于,则将 _day 减去该月的总天数,并将 _month 增加 1。如果 _month 等于 13,则将 _year 增加 1,并将 _month 重置为 1。

最后,它返回对当前对象的引用。

(注意:这里为什么是实现+=的操作,因为此时_day已经被改变,而+操作是不改变_day本身的)

Date& Date::operator+=(int day)
{
	_day += day;
	while (_day > GetMonthDay(_year, _month))
	{
		_day -= GetMonthDay(_year, _month);
		++_month;
		if (_month == 13)
		{
			++_year;
			_month = 1;
		}
	}

	return *this;
}

+操作的实现,为了不修改当前对象_day,我们需要创建一个临时变量tmp,最后返回tmp的拷贝,实现+的操作。

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

	return tmp;
}

接下来是-=和-操作的实现。

Date& Date::operator-=(int day)
{
	_day -= day;
	while (_day <= 0)
	{
		--_month;
		if (_month == 0)
		{
			--_year;
			_month = 12;
		}

		_day += GetMonthDay(_year, _month);
	}

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

	return tmp;
}

天数加减操作的测试:

int main()
{
	Date d1(2024, 2, 3);
	Date d2 = d1 + 20;
	d2.Print();
	d1.Print();

	d2 -= 20;
	d2.Print();

	d1 += 30000;
	d1.Print();
}

日期计算器的结果:


3.前置++ && 后置++

前置++:返回+1之后的结果
注意:this指向的对象函数结束后不会销毁,故以引用方式返回提高效率

Date& Date::operator++()
{
	*this += 1;
	return *this;
}

 后置++:
前置++和后置++都是一元运算符,为了让前置++与后置++形成能正确重载
     C++规定:后置++重载时多增加一个int类型的参数,但调用函数时该参数不用传递,编译器 自动传递
     注意:后置++是先使用后+1,因此需要返回+1之前的旧值,故需在实现时需要先将this保存一份,然后给this + 1,而temp是临时对象,因此只能以值的方式返回,不能返回引用

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

前置++ && 后置++的测试:

int main()
{
	Date d1(2024, 2, 3);
	++d1;
	d1.operator++();
	d1.Print();

	d1++;//此写法自动识别
	d1.operator++(0);//这种写法传参帮助编译器识别
	d1.Print();

}


4.计算天数差值

计算两个日期之间的天数差。

首先检查两个日期的大小,并将较大的日期存储在 max 中,将较小的日期存储在 min 中。

然后,它使用一个循环来计算 min 到 max 之间的天数差。

最后,它返回天数差乘以一个标志位,该标志位表示两个日期之间的天数差是正数还是负数。

int Date::operator-(const Date& d)
{
	int flag = 1;
	Date max = *this;
	Date min = d;

	if (*this < d)
	{
		int flag = -1;
		max = d;
		min = *this;
	}

	int n = 0;
	while (min != max)
	{
		++min;
		++n;
	}

	return n * flag;
}

计算天数差值函数的测试:

int main()
{
    Date d1(2024, 2, 3);
    Date d2(2024, 2, 10);
    cout << (d2 - d1) << endl;

}

距离新年还剩7天了,提前祝大家新年快乐!!!

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

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

相关文章

SOME/IP SD 协议介绍(四)服务发现通信行为

服务发现通信行为 启动行为 服务发现将根据服务实例处于以下三个阶段之一&#xff1a; • 初始等待阶段 • 重复阶段 • 主要阶段 一旦系统启动并且用于服务实例的接口连接已建立&#xff0c;服务发现将进入该服务实例的初始等待阶段。 在进入初始等待阶段并在发送第一条服…

【C++栈和队列:数据结构中的经典组合,高效处理先进先出与后进先出问题的最佳方案】

[本节目标] 1. stack的介绍和使用 2. queue的介绍和使用 3. priority_queue的介绍和使用 4. 容器适配器 1. stack的介绍和使用 1.1 stack的介绍 1. stack是一种容器适配器&#xff0c;专门用在具有后进先出操作的上下文环境中&#xff0c;其删除只能从容器的一端进行元素的…

c语言--求第n个斐波那契数列(递归、迭代)

目录 一、概念二、用迭代求第n个斐波那契数1.分析2.完整代码3.运行结果4.如果求第50个斐波那契数呢&#xff1f;看看会怎么样。4.1运行结果&#xff1a;4.2画图解释 三、用迭代的方式求第n个斐波那契数列1.分析2.完整代码3.运行结果4.求第50个斐波那契数4.1运行结果4.2运行结果…

2024/2/3 牛客寒假算法基础集训营1

目录 why买外卖 G-why买外卖_2024牛客寒假算法基础集训营1 (nowcoder.com) 要有光 L-要有光_2024牛客寒假算法基础集训营1 (nowcoder.com) why买外卖 G-why买外卖_2024牛客寒假算法基础集训营1 (nowcoder.com) 题目要求&#xff1a;这道题要求计算鸡排最贵为多少 思路&a…

C语言经典面试题——翻转单词顺序VS左旋转字符串

目录 1. 翻转单词顺序1.1 题目描述1.2 解法1.3 完整代码 2. 左旋转字符串2.1 题目描述2.1.1 解法一&#xff1a;2.1.2 解法二&#xff1a;2.1.2.1 strcpy2.1.2.2 strcat2.1.2.3 完整代码 2.1.3 解法三&#xff1a; 1. 翻转单词顺序 1.1 题目描述 输入一个英文句子&#xff0c;…

AI专题:2023年AI和标准化网络安全报告

今天分享的是AI系列深度研究报告&#xff1a;《AI专题&#xff1a;2023年AI和标准化网络安全报告》。 &#xff08;报告出品方&#xff1a;enisa&#xff09; 报告共计&#xff1a;37页 文件目的和目标 本文件的总体目标是概述与人工智能(AI)网络安全有关的标准(现有的、正在…

作业2024/2/3

第二章 引用内联重载 一&#xff0e;选择题 1、适宜采用inline定义函数情况是&#xff08;C&#xff09; A. 函数体含有循环语句 B. 函数体含有递归语句 C. 函数代码少、频繁调用 D. 函数代码多、不常调用 2、假定一个函数为A(int i4, int j0) {;}, 则执行“A (1);”语句…

三路快排解决TopK问题

前言&#xff1a; 我们首先要明白什么是三路快排&#xff0c;什么是topk问题。 三路快排&#xff1a; 思想&#xff1a; 三路快排就是数组分3块&#xff0c;三个指针&#xff0c;先随机取一个基准值key&#xff0c;然后将数组划分为3个部分&#xff1a; 【小于key】【等于…

【八大排序】冒泡排序 | 快速排序 + 图文详解!!

&#x1f4f7; 江池俊&#xff1a; 个人主页 &#x1f525;个人专栏&#xff1a; ✅数据结构冒险记 ✅C语言进阶之路 &#x1f305; 有航道的人&#xff0c;再渺小也不会迷途。 文章目录 交换排序一、冒泡排序1.1 算法步骤 动图演示1.2 冒泡排序的效率分析1.3 代码实现1.4 …

【Vue】组件间通信的7种方法(全)

目录 组件之前的通信方法 1. props/$emit 2.parent/children 3.ref 4.v-model 5.sync 6.attrs,attrs,attrs,listeners 7.provide/inject 7.eventBus 组件之前的通信方法 1. props/$emit 父传子 props 这个只能够接收父组件传来的数据 不能进行修改 可以静态传递 也可…

【计算机视觉】目标检测 |滑动窗口算法、YOLO、RCNN系列算法

一、概述 首先通过前面对计算机视觉领域中的卷积神经网络进行了解和学习&#xff0c;我们知道&#xff0c;可以通过卷积神经网络对图像进行分类。 如果还想继续深入&#xff0c;会涉及到目标定位(object location)的问题。在图像分类的基础上(Image classification)的基础上…

Maven快速入门——基础篇

本篇对Maven基础进行总结&#xff0c;主要对Maven的定义、作用、Maven坐标、依赖管理、依赖配置、依赖传递特性以及Maven的生命周期进行总结&#xff0c;后面会对springboot以及Maven高级进行总结。 文章目录 目录 一、Maven是什么&#xff1f; 二、Maven的作用&#xff1a; 三…

基于YOLOv8深度学习的水稻叶片病害智能诊断系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

openGauss学习笔记-213 openGauss 性能调优-总体调优思路

文章目录 openGauss学习笔记-213 openGauss 性能调优-总体调优思路213.1 调优思路概述213.2 调优流程 openGauss学习笔记-213 openGauss 性能调优-总体调优思路 213.1 调优思路概述 openGauss的总体性能调优思路为性能瓶颈点分析、关键参数调整以及SQL调优。在调优过程中&…

python使用两个栈实现队列

这里主要是使用两个栈来实现一个队列,并实现队列的入队和出队函数。 对于一个单词hello,如果正常情况下按照队列中先进先出的特点,会按照hello的顺序入队,同样也会按照hello的顺序出队。 添加图片注释,不超过 140 字(可选) 因此如果想要利用两个栈来形成队列,就要将后…

基于SpringBoot+Vue的高校在线答疑管理系统

末尾获取源码作者介绍&#xff1a;大家好&#xff0c;我是墨韵&#xff0c;本人4年开发经验&#xff0c;专注定制项目开发 更多项目&#xff1a;CSDN主页YAML墨韵 学如逆水行舟&#xff0c;不进则退。学习如赶路&#xff0c;不能慢一步。 目录 一、项目简介 二、开发技术与环…

前端学习笔记 | 响应式网页+Boostrap

一、响应式网页 一套代码适应多端 1、媒体查询media(条件){css} max-width 小于等于max-width生效min-width 【案例】左侧隐藏 因为CSS的层叠性&#xff0c;书写顺序&#xff1a;max-width从大到小&#xff1b;min-width从小到大。 【媒体查询完整写法】 在html中link用于不同…

JSP和JSTL板块:第二节 JSP的指令和动作 来自【汤米尼克的JAVAEE全套教程专栏】

JSP和JSTL板块&#xff1a;第二节 JSP的指令和动作 一、page指令&#xff1a;页面设置&#xff08;1&#xff09;导入包&#xff1a;import属性&#xff08;2&#xff09;设定字符集&#xff1a;pageEncoding属性&#xff08;3&#xff09;设定错误页面&#xff1a;errorPage/i…

Docker上安装配置tomcat

目录 1. 拉取镜像 2. 创建运行镜像 3. 查看是否创建成功 ps&#xff1a;如果出现404错误 tomcat目录结构 1. 拉取镜像 这里使用 tomcat:8.5.40 版本作为安装 docker pull tomcat:8.5.40 2. 创建运行镜像 docker run -d --name tomcat -p 8080:8080 \--privilegedtrue …

day07-CSS高级

01-定位 作用&#xff1a;灵活的改变盒子在网页中的位置 实现&#xff1a; 1.定位模式&#xff1a;position 2.边偏移&#xff1a;设置盒子的位置 left right top bottom 相对定位 position: relative 特点&#xff1a; 不脱标&#xff0c;占用自己原来位置 显示模…
最新文章