C++ 日期计算器的实现(运算符重载)

目录

一、前言

二、正文

1.1 Date类框架

1.2 两个日期间的直接赋值

1.3判断两个日期是否相同

1.4判断两个日期是否不同

 1.5日期加天数

1.6日期+=天数

1.7日期的前置++和后置++

1.8日期减天数

1.9自身日期减天数

2.1自身日期前置--和后置--

 2.2两个日期的差值为差距天数

2.3判断两个日期的关系(<或<=)

2.4判断两个日期的大小(>和>=)

2.5重载运算符输入>>和输出<<(>>和<<其实是流)

 三、结语


一、前言

前面我们已经分享了有关C++中运算符重载的一些相关知识,现在让我们运用这些知识写一个日期计算器吧。

二、正文

1.1 Date类框架

class Date
{
public:
Date(int year = 2024, int month = 11, int day = 20)//构造函数
{_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;
};

1.2 两个日期间的直接赋值

Date& operator=(const Date& d)//两个日期之间的直接赋值拷贝
{_year = d._year;_month= d._month;_day = d._day;return *this;
}

1.3判断两个日期是否相同

	bool operator==(const Date& d)//判断两个日期是否日期相同,相同返回true,不相同返回false{return _year == d._year &&_month == d._month &&_day == d._day;}

1.4判断两个日期是否不同

bool operator!=(const Date& d)//判断两个日期是否相同,不相同返回true,相同返回false
{if (_year != d._year)return true;if (_month != d._month)return true;if (_day != d._day)return true;return false;
}

 1.5日期加天数

int CheckDayCount(int year,int month)//获得当月的天数{int Day[] = { 0,31,28,31,30,31,30,31,31,30,31,30 ,31 };if (month==2&&year % 4 == 0 && year % 400 == 0){return 29;}return Day[month];
}Date operator+(int x)//日期加天数
{Date tmp(*this);tmp._day = tmp._day + x;while (tmp._day > tmp.CheckDayCount(tmp._year,tmp._month)){tmp._day = tmp._day - tmp.CheckDayCount(tmp._year, tmp._month);tmp._month++;if (tmp._month == 13){tmp._month = 0;tmp._year++;}}return tmp;
}

在日期加天数这个函数中,我们需要用到CheckDateCount这个成员函数,这个函数是输出某月的天数(比如11月返回30天,2月根据平年和闰年分别返回28,29天)。

operator+的实现原理是:我们先将要加的天数x直接加到*this的拷贝tmp中(注意这里不能改变*this的成员,就比如一个整形a,我们让它加1就是a+1,在这个a+1过程中a是没有改变的,这里我们用tmp拷贝*this就是类似这里不想改变”a“的值一样)如果tmp.day大于tmp.month所代表的的天数,这里就设为Day(这里我们是通过CheckDateCount实现返回某月天数的)

那么我们就拿tmp.day-Day,tmp.day-Day执行一次tmp.month++一次。如果tmp.month>12(一年只有12个月),那么tmp.year++,并且让tmp._month=1。

直到tmp.day<=Day,while循环结束。

例子:初始tmp._year=2024,tmp._month=11.tmp._day=20。

我们让tmp+100(x=100),tmp就有:tmp._year=2024,tmp._month=11,tmp._day=120。

第一次循环:因为tmp._day(120)>30(CheckDateCount(2024,11),11月是30天)进入while循环:

tmp.day(120)=tmp._day-30(CheckDateCount(2024,11),11月是30天)->tmp._day=90。

tmp._month++(11+1=12);

第二次循环:因为tmp._day(90)>31(CheckDateCount(2024,11),12月是31天)进入while循环:

tmp._day(90)=tmp._day-31(CheckDateCount(2024,11),12月是31天)->tmp._day(59)

tmp._month++(12+1=13)。因为tmp._month(13)>12。所以让tmp._year++(2024+1=2025)

并且让tmp._month=1。

第三次循环:  因为tmp._day(59)>31(CheckDateCount(2024,12),1月是31天)进入while循环:

tmp._day(59)=tmp._day-31(CheckDateCount(2024,1),1月是31天)->tmp._day(28)

tmp._month++(1+1=2)。

此时准备第四次循环,发现tmp._day(28)=28(CheckDateCount(2024,2),2025年是平年,所以2月是28天)不进入第四次循环,循环结束

operator+返回tmp,其中tmp._year=2025、tmp._month=2、tmp._day=28。函数结束。

1.6日期+=天数

	Date& operator+=(int x)//自身日期加天数{*this = *this + x;return *this;}

 *this=*this+x中,这个=其实是我们上面写得operator+(成员函数之间可以相互复用)

下面我们写的一些运算符重载函数中,也有一些运算符重载函数复用了其他运算符重载函数。例如我们这里operator+=就复用了operator+。

1.7日期的前置++和后置++

Date& operator++()
{//这里是前置++*this += 1;return *this;
}
//上下两个都是operator++,那么编译器如何分辨什么时候是前置++,
//什么时候是后置++呢
//为了区分两者,C++规定必须给后置++,强行增加一个int形参
//这个形参可以不用管它,这个参数仅仅是为了区分前置++和后置++用的,无实际意义。
Date operator++(int)
{//这里是后置++Date tmp(*this);*this += 1;return tmp;
}

1.8日期减天数

Date operator-(int x)//日期减天数:例如:d1-100
{Date tmp(*this);tmp._day = tmp._day - x;while (tmp._day < 0){tmp._month--;if (_month == 0){tmp._year--;}tmp._day = tmp._day + tmp.CheckDayCount(tmp._year, tmp._month);}return tmp;
}

1.9自身日期减天数

Date& operator-=(int x)//自身日期减天数 例如:d1-=100
{*this = *this - x;return *this;
}

2.1自身日期前置--和后置--

Date& operator--()//例如:--d1。
{//这里是前置--*this -= 1;return *this;
}
Date operator--(int)//例如:d1--。
{//这里是后置--Date tmp(*this);*this -= 1;return tmp;
}

 这里的分别前置--和后置--的区别方法和上面前置++和后置++一样。

 2.2两个日期的差值为差距天数

int operator-(const Date& d)//两个日期的差值表示差距天数 例如:d1-d2返回天数
{Date min = d;Date max = *this;int flag = 1;int count = 0;if (*this <= d){min= *this;max = d;flag = -1;
}while (min!=max){min++;count++;}return count*flag;
}

这个函数的思想是:我们首先假设日期*this是大于d的,则有min=d;max=*this。当*this>d

的时候,我们另flag=1表示正数(为了方便表示*this-d>0)。

反之,如果实际上,*this<=d,则另min=*this,max=d。flag=-1(为了方便表示*this-d<0)

因为min<ma=x,那么min一直累加到和max相同这个过程的次数,就是min与max的差值,即是日期*this和日期d之间相差的天数。如果*this<d输出的值就是负数。反之就是正数或是0。

这个时候我们定义的flag就是起到了表示函数返回的天数是正数还是负数的功能。

比如这里:

假设*this(2024,11,20)、d(2025,11,20)因为*this<d。所以min=*this、max=d、

flag=-1。min一直++,一直加到min=max,这个过程中min++的次数count就是min和max的差值。即也是*this和d相差的天数。这里我们返回count*flag=365*(-1)=-365。

2.3判断两个日期的关系(<或<=)

	bool operator<=(const Date& d) const//判断一个日期是否小于等于另外一个日期{return d >= *this;//这里复用了我们上面写的operator>=,通过复用就可以使代码更加简洁。}bool operator < (const Date& d) const //判断一个日期是否小于另外一个日期{return d > *this;}

2.4判断两个日期的大小(>和>=)

bool operator >= (const Date& d)const//判断一个日期是否大于等于另外一个日期
{return  _year >= d._year && _month >= d._month && _day >= d._day;
}
bool operator>(const Date& d)const// const//判断一个日期是否大于另外一个日期
{if (_year > d._year){return true;}if (_month > d._month){return true;}if (_day > d._day){return true;}return false;
}

2.5重载运算符输入>>和输出<<(>>和<<其实是流)

ostream& operator<<(ostream& out,const Date& d)//运算符重载输出语句
{out << d._year << "年" << d._month << "月" << d._day << "日" << endl;return out;
}
istream& operator>>(istream& in,  Date& d)//运算符重载输入语句
{cout << "请输入年月日:" << endl;in >> d._year >> d._month >> d._day;while (d._month > 12 || d._day<0 || d._day>d.CheckDayCount(d._year, d._month)){cout << "输入日期有误!" << endl;cout << d;cout << "请重新输入:" << endl;in >> d._year >> d._month >> d._day;}return in;
}

 上面这两个函数我们并没有定义在Date类中,而是定义在全局中。为了能在Date类外面能访问到类成员属性(_year,_month,_day)我们这里使用了友元函数的功能。

友元函数类似一个通行证,只要在类中这样表示:friend后跟类外的一个函数。这样这个类外函数就可以访问到我们的类成员属性了。

类似如下:

 三、结语

 日期计算器的实现就到这里了,帅哥美女们咱们下次再见

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LLM的原理理解6-10:6、前馈步骤7、使用向量运算进行前馈网络的推理8、注意力层和前馈层有不同的功能9、语言模型的训练方式10、GPT-3的惊人性能

目录 LLM的原理理解6-10: 6、前馈步骤 7、使用向量运算进行前馈网络的推理 8、注意力层和前馈层有不同的功能 注意力:特征提取 前馈层:数据库 9、语言模型的训练方式 10、GPT-3的惊人性能 一个原因是规模 大模型GPT-1。它使用了768维的词向量,共有12层,总共有1.…

如何使用 Python 开发一个简单的文本数据转换为 Excel 工具

目录 一、准备工作 二、理解文本数据格式 三、开发文本数据转换为Excel工具 读取CSV文件 将DataFrame写入Excel文件 处理其他格式的文本数据 读取纯文本文件: 读取TSV文件: 四、完整代码与工具封装 五、使用工具 六、总结 在数据分析和处理的日常工作中,我们经常…

太通透了,Android 流程分析 蓝牙enable流程(应用层/Framework/Service层)

零. 前言 由于Bluedroid的介绍文档有限&#xff0c;以及对Android的一些基本的知识需要了(Android 四大组件/AIDL/Framework/Binder机制/JNI/HIDL等)&#xff0c;加上需要掌握的语言包括Java/C/C等&#xff0c;加上网络上其实没有一个完整的介绍Bluedroid系列的文档&#xff0…

李继刚:提示词(Prompt)的本质是表达的艺术

看了李继刚在 AI 创新者大会的演讲《提示词的道与术》&#xff0c;收获很大&#xff0c;我分享一下学习笔记。  李继刚&#xff1a;提示词&#xff08;Prompt&#xff09;的本质是表达的艺术 一、提示词的本质是表达 本意、文意和解意的概念&#xff1a; 本意&#xff1a;指…

复古风格渐变褪色人像旅拍Lr调色教程,手机滤镜PS+Lightroom预设下载!

调色教程 这种调色风格旨在通过调整色彩和光影&#xff0c;为人像旅拍照片赋予复古的氛围和艺术感。渐变褪色效果增添了一种时光沉淀的感觉&#xff0c;使照片仿佛来自过去的岁月。 预设信息 调色风格&#xff1a;复古风格预设适合类型&#xff1a;人像&#xff0c;街拍&…

Android Studio更改项目使用的JDK

一、吐槽 过去&#xff0c;在安卓项目中配置JDK和Gradle的过程非常直观&#xff0c;只需要进入Android Studio的File菜单中的Project Structure即可进行设置&#xff0c;十分方便。 原本可以在这修改JDK: 但大家都知道&#xff0c;Android Studio的狗屎性能&#xff0c;再加…

字节青训营开课啦

系列文章目录 文章目录 系列文章目录一、字节青训营是什么&#xff1f;二、你将获得三、入营条件四、课程简介1.前端2.后端3.大数据 五、报名 一、字节青训营是什么&#xff1f; 青训营是字节跳动技术团队发起的技术系列培训&人才选拔项目&#xff1b;面向高校在校生&…

医药企业的终端市场营销策略

近年来&#xff0c;随着医药行业的快速发展&#xff0c;终端市场逐渐成为企业竞争的关键领域。在政策趋严、市场环境变化以及数字化转型的大背景下&#xff0c;医药企业如何在终端市场中立于不败之地&#xff1f;本文结合我们在医药数字化领域的经验&#xff0c;为大家剖析终端…

养老院管理系统+小程序项目需求分析文档

智慧综合养老服务平台是以业务为牵引、场景为驱动&#xff0c;围绕“老人”业务域&#xff0c;持续沉淀和打磨形成适应不同养老业务发展需要的业务能力&#xff0c;推动业务模式升级&#xff0c;为养老服务提供数字化解决方案&#xff0c;并依托实体站点与养老机构实现线上线下…

SpringBoot集成ES(ElasticSearch)

1.导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>导入依赖后&#xff0c;注意在依赖中查看对应的版本是否与本机ES对应 2.创建配置并…

数据结构之二:表

顺序表代码&#xff1a;SData/SqList/SeqList.h Hera_Yc/bit_C_学习 - 码云 - 开源中国 链表相关代码&#xff1a;SData/ListLink/main.c Hera_Yc/bit_C_学习 - 码云 - 开源中国 本文主要讲解的是线性表&#xff08;逻辑线性&#xff09;&#xff0c;对于非线性表不做补充。…

《Python基础》之循环结构

目录 简介 一、for循环 1、基本语法与作用 2、使用 range() 函数配合 for 循环 3、嵌套的for循环 二、while循环 1、基本语法与作用 2、while 循环嵌套 &#xff08;1&#xff09;、while循环与while循环嵌套 &#xff08;2&#xff09;、while循环与for循环嵌套 简介 …

基于LiteFlow的风控系统指标版本控制

个人博客&#xff1a;无奈何杨&#xff08;wnhyang&#xff09; 个人语雀&#xff1a;wnhyang 共享语雀&#xff1a;在线知识共享 Github&#xff1a;wnhyang - Overview 更新日志 最近关于https://github.com/wnhyang/coolGuard此项目更新了如下内容&#xff1a;https://g…

Mysql中的 TEXT 和 BLOB 解析

&#x1f680; 博主介绍&#xff1a;大家好&#xff0c;我是无休居士&#xff01;一枚任职于一线Top3互联网大厂的Java开发工程师&#xff01; &#x1f680; &#x1f31f; 在这里&#xff0c;你将找到通往Java技术大门的钥匙。作为一个爱敲代码技术人&#xff0c;我不仅热衷…

241124_文本解码原理

241124_文本解码原理 一个文本序列的概率分布可以分解为每个词基于其上文的条件概率的乘积。 Greedy search 就是每步都选择概率最大的&#xff0c;不会去考虑全局 按照贪心搜索输出the nice woman 的概率就是0.5*0.40.2 这种方法简单&#xff0c;但也存在问题&#xff0c;比…

介绍一下strlwr(arr);(c基础)

hi , I am 36 适合对象c语言初学者 strlwr(arr)&#xff1b;函数是把arr数组变为小写字母 格式 #include<string.h> strlwr(arr); 返回值为arr 链接分享一下arr的意义(c基础)(必看)(牢记)-CSDN博客 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #incl…

16:(标准库)ADC三:使用外部触发启动ADC/模拟看门狗

使用外部触发启动ADC 1、外部中断线EXTI11触发ADC2、外部定时器TIM2_CH2触发ADC3、ADC中模拟看门狗的使用 1、外部中断线EXTI11触发ADC ADC的触发方式有很多&#xff0c;一般情况都是使用软件触发反式启动ADC转换。除了软件触发方式还能使用外部事件触发启动ADC转换。如下图所…

Linux之管道,system V的共享内存,消息队列和信号量

Linux之管道&#xff0c;systemV共享内存和信号量 一.进程间通信1.1进程间通信的目的1.2进程间通信的方式 二.管道2.1管道的概念2.2匿名管道2.3命名管道 三.system V3.1共享内存3.2消息队列3.3信号量 一.进程间通信 在我们之前有关Linux指令的学习时我们使用过“|”这个命令&a…

使用ChatGPT生成和优化电子商务用户需求规格说明书

在电子商务项目开发中&#xff0c;用户需求规格说明书&#xff08;User Requirement Specification, URS&#xff09;是团队沟通与项目成功的基石。然而&#xff0c;面对复杂多变的需求&#xff0c;如何快速生成清晰、完整且具备说服力的文档&#xff1f;这正是AI工具的用武之地…

1+X应急响应(网络)常见网络攻击-SQL注入:

常见网络攻击-SQL注入&#xff1a; SQL注入概述&#xff1a; 动态网站的工作流程&#xff1a; SQL注入的起源&#xff1a; SQL典型的攻击手段&#xff1a; SQL注入的危害&#xff1a; SQL注入的函数&#xff1a; SQL注入类型&#xff1a; 提交方式分类&#xff1a; Get注入&am…