【c++】简单的日期计算器

Alt

🔥个人主页Quitecoder

🔥专栏c++笔记仓

Alt

朋友们大家好啊,在我们学习了默认成员函数后,我们本节内容来完成知识的实践,来实现一个简易的日期计算器

目录

  • 头文件声明函数
  • 函数的实现
      • 1.全缺省默认构造函数
      • 2.拷贝构造函数
      • 3.七个个运算符重载
      • 4.日期计算函数
      • 5.前后置加加减减
      • 6.两个对象直接相减

头文件声明函数

头文件声明所有函数:

#pragma once
#include<iostream>

using namespace std;

class Date
{
public:
	int GetMonthDay(int year, int month)
	{
		static int days[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31,30,31 };
		int day = days[month];
		if (month == 2
			&& ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
		{
			day += 1;
		}
		return day;
	}
	// 全缺省的构造函数
	Date(int year = 1, int month = 1, int day = 1);
	// 拷贝构造函数
 // d2(d1)
	Date(const Date& d);

	// 赋值运算符重载
    // d2 = d3 -> d2.operator=(&d2, d3)
	Date& operator=(const Date& d);
	// 析构函数
	~Date();
	// 日期+=天数
	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);
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

函数的实现

第一个函数,获取某月天数

class Date
{
public:
	int GetMonthDay(int year, int month)
	{
		static int days[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31,30,31 };
		int day = days[month];
		if (month == 2
			&& ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
		{
			day += 1;
		}
		return day;
	}

为了按照月的月份直接访问数组,我们设置大小为13,由于要进行多次访问,我们可以将数组变量设置在全局

如果是闰年,则二月为29天,返回某个月的天数

1.全缺省默认构造函数

Date::Date(int year, int month, int day)
{
	_year = year;
	_month = month;
	_day = day;
}

在头文件进行缺省,源文件不需要

2.拷贝构造函数

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

3.七个个运算符重载

这里总共有七个运算符,除了赋值运算符外,我们只需要得到特殊的两个就可以简单的写出另外四个函数

首先,的重载

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

我们再写一个<的重载

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

按照年月日逐次判断

上面两个完成后,其余的就很简单了

小于等于,就是小于或者等于

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

赋值运算符重载

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

4.日期计算函数

自身增加天数

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

如果天数超过某个月,则天数减去当前这个月,让月份增加,如果月数等于13了,则年进一,月份重置为1月

有了加等,实现加就很简单了

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

	return tmp;
}

这两个有什么区别呢??

这两个函数都是Date类的成员函数,用于对日期进行增加天数的操作,但它们在用法和效果上有所不同。

Date& Date::operator+=(int day)

这个函数重载了+=运算符,允许你直接在当前对象上增加天数。它会修改调用它的对象本身,并返回修改后对象的引用。

特点

  • 直接修改:它修改调用对象的状态,即增加的天数直接反映在原对象上
  • 返回引用:返回调用它的对象的引用,允许链式操作

用法示例

Date d1(2020, 3, 30); // 假设是2020年3月30日
d1 += 3; // 在d1上增加3天
// d1现在是2020年4月2日

Date Date::operator+(int day)

这个函数重载了+运算符,允许你在一个临时对象上增加天数,而不改变原始对象。它通过创建一个当前对象的副本,然后在这个副本上应用+=操作,最后返回这个修改后的副本

特点

  • 不直接修改:它不会修改原始调用对象的状态,而是返回一个新的修改后的对象。
  • 返回对象:返回一个新的Date对象,这个对象是在原对象基础上增加天数后的结果。

用法示例

Date d2(2020, 3, 30); // 假设是2020年3月30日
Date d3 = d2 + 3; // 在d2的基础上增加3天,但d2本身不变
// d2仍然是2020年3月30日
// d3是2020年4月2日
  • operator+=是一个修改原对象并返回其引用的成员函数,用于实现“就地修改”。
  • operator+是一个返回新对象的成员函数,它在不修改原对象的情况下返回增加天数后的新日期对象。

我们现在是加等嵌套在加里面,如果反过来呢?
在这里插入图片描述

对比我们能发现,两种加法都要创建一个新的变量,效果相同,但是加等,右边复用加的时候又创建对象,对比左边效率降低,所以用加复用加等效果更好

同理完成日期的减等和减

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

5.前后置加加减减

这里我们已经上篇文章讲解过了,直接进行代码的实现

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

6.两个对象直接相减

两个对象直接相减得到相差的日期天数:

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

这个实现逻辑首先确定哪个日期较大,然后不断将较小的日期递增,直到它与较大的日期相等,过程中累计递增的天数,最终返回这个天数。如果初始的第一个日期小于第二个日期,返回的天数会是负值

让我们分析一下代码的关键部分:

  1. 确定日期大小:代码首先比较两个日期,确保max总是较大的日期,而min是较小的日期。flag变量用于记录原始日期的相对顺序,如果需要反转(即第一个日期小于第二个日期),flag会被设置为-1

  2. 计算天数差:通过一个循环,每次将min日期递增一天(使用operator++),直到min等于max。每次递增都会将n加1,n用于记录两个日期之间相差的天数

  3. 返回结果:最后,返回累计的天数n乘以flag。如果flag-1,表示第一个日期实际上是小于第二个日期的,因此返回负值

本节内容到此结束,感谢大家阅读!

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

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

相关文章

手机真机连接USB调试adb不识别不显示和TCPIP连接问题

手机真机连接USB调试adb devices不显示设备和TCPIP连接 本文手机型号为NOVA 7 &#xff0c;其他型号手机在开发人员模式打开等方式可能略有不同&#xff0c;需根据自己的手机型号修改。 文章目录 1. 打开和关闭开发者模式2. 真机USB连接调试adb不显示设备问题的若干解决方法3…

CKS之安全沙箱运行容器:gVisor

目录 一、gVisor介绍 二、gVisor架构 三、gVisor使用前置条件 四、Docker中使用gVisor 五、containerd中使用gVisor 六、Kubernetes结合gVisor使用 一、gVisor介绍 gVisor是Google开源的一种容器沙箱技术&#xff0c;其设计初衷是在提供较高安全性的同时&#xff0c;尽量…

二十四种设计模式与六大设计原则(一):【策略模式、代理模式、单例模式、多例模式、工厂方法模式、抽象工厂模式】的定义、举例说明、核心思想、适用场景和优缺点

目录 策略模式【Strategy Pattern】 定义 举例说明 核心思想 适用场景 优缺点 代理模式【Proxy Pattern】 定义 举例说明 核心思想 适用场景 优缺点 单例模式【Singleton Pattern】 定义 举例说明 核心思想 适用场景 优缺点 多例模式【Multition Pattern】…

【2023】kafka在linux和docker安装(kafka-1)

目录&#x1f4bb; 一、linux安装kafka1. 安装jdk2. 上传解压到/usr/local目录下3、使用kafka 二、docker安装kafka1. 下载2. 安装zookeeper3. 安装kafka 一、linux安装kafka 环境主机 mac m2、虚拟机Ubuntu22.04.4 1. 安装jdk yum install -y java-1.8.0-openjdk.x86_64下载k…

.NET使用HttpClient以multipart/form-data形式post上传文件及其相关参数

前言&#xff1a; 本次要讲的是使用.Net HttpClient拼接multipark/form-data形式post上传文件和相关参数&#xff0c;并接收到上传文件成功后返回过来的结果&#xff08;图片地址&#xff0c;和是否成功&#xff09;。可能有很多人会说用ajax不是就可以轻松的实现吗&#xff1f…

最优算法100例之16-连续子数组的最大和

专栏主页:计算机专业基础知识总结(适用于期末复习考研刷题求职面试)系列文章https://blog.csdn.net/seeker1994/category_12585732.html 题目描述 输入一个整型数组,数组里有正数也有负数。 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。 题…

Datacom HCIP笔记-OSPF协议 之二

链路&#xff1a;路由器之间的相连的链路 状态&#xff1a;链路上的参数在某一时刻的状态 单边邻居 one way&#xff1f; 收到对端发来的hello报文&#xff0c;其中没有自己的router id LSA类型&#xff1a; 1类LSA&#xff1a;描述路由器自身加入到ospf进程中的直连链路的状态…

wps没保存关闭了恢复数据教程

有时候我们因为电脑问题会忘记保存就关闭wps导致数据丢失&#xff0c;不知道wps没保存关闭了怎么恢复数据&#xff0c;其实数据是无法恢复的。 wps没保存关闭了怎么恢复数据 1、wps没有数据恢复功能&#xff0c;不过可以开启自动备份。 2、我们可以先点击wps左上角的“文件”…

Adaboost集成学习 | Matlab实现基于BiLSTM-Adaboost双向长短期记忆神经网络结合Adaboost集成学习时间序列预测(股票价格预测)

目录 效果一览基本介绍模型设计程序设计参考资料效果一览 基本介绍 Matlab实现基于BiLSTM-Adaboost双向长短期记忆神经网络结合Adaboost集成学习时间序列预测(股票价格预测) 模型设计 股票价格预测是一个具有挑战性的时间序列预测问题,可以使用深度学习模型如双向长短期记忆…

书生·浦语全链路开源开放体系 第二期

文章目录 大模型背景大模型开发流程InternLM 2.0SFT与RLHFInternLM2主要亮点 书生浦语全链路开源开放体系数据-书生万卷InternLM-Train微调 XTuner评测工具 OpenCompass部署 LMDeploy智能体 Lagent智能体工具箱 AgentLego 大模型背景 专用模型&#xff1a;针对特定的任务&…

ChatGPT如何升级为GPT-4在国内

通过 WildCard 可以把ChatGPT升级为GPT-4 地址 1: 2155 Bailey Hill Rd 城市: Eugene 邮编: 97405 州: Oregon ChatGPT Plus/Team 一键升级&#xff0c;几分钟即可自动升级到 ChatGPT Plus。 选择我的邮箱账号符合要求 复制这个页面的链接即可 复制上面的link 到请在…

【ReadPapers】A Survey of Large Language Models

LLM-Survey的llm能力和评估部分内容学习笔记——思维导图 思维导图 参考资料 A Survey of Large Language Models论文的github仓库

适用于 Windows 的 6 个最佳视频转换器

视频转换器可以帮助您在设备上转换和播放不受支持的视频格式。它还可以方便地减小视频文件大小、以通用格式组织所有视频或与其他人共享文件以在不同设备上播放。 Windows 有大量视频转换器可供选择。虽然有些是免费的&#xff0c;但其他一些则提供迎合专业用户的高级功能。在…

深度学习pytorch——经典卷积网络之ResNet(持续更新)

错误率前五的神经网络&#xff08;图-1&#xff09;&#xff1a; 图-1 可以很直观的看到&#xff0c;随着层数的增加Error也在逐渐降低&#xff0c;因此深度是非常重要的&#xff0c;但是学习更好的网络模型和堆叠层数一样简单吗&#xff1f;通过实现表明&#xff08;图-2&…

神经网络 各个模块介绍(Pytorch 07)

一 网络层和块 单个神经网络&#xff08;1&#xff09;接受一些输入&#xff1b;&#xff08;2&#xff09;生成相应的标量输出&#xff1b;&#xff08;3&#xff09;具有一组相关 参数&#xff08;parameters&#xff09;&#xff0c;更新这些参数 可以优化某目标函数。 当…

排序第五篇 归并排序

一 简介 归并排序(Merge Sort) 的基本思想是&#xff1a; 首先将待排序文件看成 n n n 个长度为1的有序子文件&#xff0c; 把这些子文件两两归并&#xff0c; 得到 n 2 \frac{n}{2} 2n​ 个长度为 2 的有序子文件&#xff1b; 然后再把这 n 2 \frac{n}{2} 2n​ 个有序的子…

Go-React做一个todolist(服务端)【一】项目初始化

后端仓库地址 地址 项目依赖 # gin go get -u github.com/gin-gonic/gin # viper日志 go get -u github.com/spf13/viper # 数据库和gorm go get -u gorm.io/driver/mysql go get -u gorm.io/gorm # uuid go get -u github.com/google/uuid # token go get -u github.com/go…

cron服务

Cron文件&#xff1a;Cron服务使用一个特定的配置文件来存储任务和其执行计划。在Unix系统上&#xff0c;这个文件通常是 /etc/crontab&#xff0c; 或者是位于/etc/cron.d/目录下的其他文件。 这些文件包含了任务的定义&#xff0c;包括执行时间和要执行的命令。 类似于 编…

JavaSE:继承和多态(上篇)

目录 一、前言 二、继承 &#xff08;一&#xff09;继承概念 &#xff08;二&#xff09;继承的语法 &#xff08;三&#xff09;父类成员访问 1.子类中访问父类的成员变量 1.1子类和父类不存在同名成员变量 1.2子类和父类成员变量同名 2.子类中访问父类的成员方法 &a…

SOA-面向服务架构

SOA-面向服务架构 1.概述2.SOA的设计原则包括&#xff1a;3. SOA实现方法1.Web Service2. 服务注册表3. 企业服务总线 细讲 超赞笔记 1.概述 SOA &#xff08;Service-Oriented Architecture&#xff0c;SOA&#xff09;&#xff0c;从应用和原理的角度&#xff0c;目前有2种…