C++初阶 日期类的实现(上)

目录

一、前置准备

1.1获得每月的天数

1.2获得每年的天数

1.3构造函数,析构函数和拷贝构造函数

二、日期与天数的+,-,+=,-=实现

2.1+=运算符重载

2.2+运算符的实现

2.3-=运算符的实现

2.4-运算符的实现

三、++,--的实现

3.1前置++,后置++的实现

3.2前置--和后置--的实现

四、下期预告


前言:C++初阶系列,每一期博主都会使用简单朴素的语言将对应的知识分享给大家,争取让所有人都可以听懂,C++初阶系列会持续更新,上学期间将不定时更新,但总会更的

一、前置准备

1.1获得每月的天数

每月的天数是一个很重要的东西,其中二月最为特殊,闰年的时候它是29,其余年份为28,我们可以使用数组的方式来进行操作,而这个数组的创建也是有讲究的,创建为13的长度最好。

因为数组的下标从0开始,而日期是从1开始的,如此我们若是想要月份和数组的下标一一对应,就得放弃一个空间,所以我们创建的长度为13,创建完数组之后第一个下标的值给0即可,从下一个下标的值开始给月份对应的天数,给完之后再在外面对闰年的情况单独处理一下,最后返回对应月份的天数就完成了。

	int GetMonthDay(int year, int month){int arr[13] = { 0,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;}return arr[month];}

1.2获得每年的天数

这个操作比之前更加简单,判断下是否是闰年即可,不多说,直接上代码

	int GetYearDay(int year){if ((_year % 4 == 0 && _year % 100 != 0) || _year % 400 == 0)return 366;return 365;}

1.3构造函数,析构函数和拷贝构造函数

这方面是很基本的,具体的实现过程我就不赘述了,如果有小伙伴不懂,可以去看看博主之前写的博客C++ 初阶 类和对象(中)-CSDN博客 C++初阶 类和对象(下)-CSDN博客

注意:构造函数构造的日期不一定合法,可以来个判断语句,若非法,中止程序

直接上代码

	Date(int year=1,int month=1,int day=1)//构造函数{if (year < 1 || month>12 || day > GetMonthDay(year, month)){cout << "日期非法,创建失败" << endl;exit(-1);//退出程序}_year = year;_month = month;_day = day;}Date(const Date&d1)//拷贝构造函数{_year = d1._year;_month = d1._month;_day = d1._day;}~Date()//析构函数{_year = 0;_month = 0;_day = 0;}

二、日期与天数的+,-,+=,-=实现

2.1+=运算符重载

目标:实现一个日期+天数,日期被修改为过了多少天的日期

很多人第一次写会写成这样,而编译器报错是因为多了一个this指针过去,已经达到了三目运算符的操作了   因此我们只需要把Date d1去掉即可,但因为有this指针的存在,我们一样能对这个变量进行操作。

实现这个之前我们可以写一个GetMonthDay函数来获得没一月份的天数,值得注意的一点是闰年时2月为29日,接着我们来讲讲实现思路,我们的返回值最好设置成Date&型的,因为+=操作的目标出了函数作用域在main中依然存在,因此使用Date&类型的返回值可以令编译器的效率得到提高。

可以先在目标的_day上加上day,这样能方便之后的进位,比方说2023-11-16 +100就先处理成2023-11-116,之后通过GetMonthDay取得的具体进位数据来进行进位即可,这里就可以通过循环实现,当_day>GetMonthDay时意味着需要进位,因此可以以这个来作为循环是否继续的条件,之后的实现便只需要注意一些细节即可,比方说,月满12进1之类的。

	int GetMonthDay(int year, int month){int arr[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//之所以是13是为了更加符合日期的返回,一月就返回数组下标为1的值if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)){return 29;}return arr[month];}Date& operator +=(int day){_day += day;while (_day > GetMonthDay(_year,_month)){_day -= GetMonthDay(_year, _month);_month++;if (_month>12){_month = 1;_year++;}}return *this;}

测试: 

2.2+运算符的实现

有了+=运算符之后+运算符就很好操作了,复用一下就好 

使用临时变量的原因是因为,+运算符并不改变原来变量的值,比方说a=b+100;这里的b也不会被修改

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

2.3-=运算符的实现

 这个实现起来和+=有着异曲同工之处,都可以先直接在对象的_day上-day,比方说2023-11-17-100,就直接先转换为2023-11-(-83),然后通过月份的进位来不断的令_day增加,直到_day大于0的时候循环停止并返回对应的内容即可。

注意:月份和天数在进行--的时候是不可能出现0的,大家应该都没听过0天,0月这种说法吧,因此在条件判断语句中应该要把0也考虑进去。

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

测试:

2.4-运算符的实现

如+运算符一样简单的复用一下即可

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

三、++,--的实现

3.1前置++,后置++的实现

有了+=和+运算符之后做这步是很简单的,唯一需要注意的是后置++的那个++运算符在重载的时候参数中要多来个int,注意:前置++,先++后使用,后置++先使用后++

关于这方面更详细的讲解请看博主之前写的文章 

C++初阶 类和对象(下)-CSDN博客

	Date& operator++()//前置++,先++后使用{(*this) += 1;return *this;}Date operator++(int)//后置++,先使用后++{Date tmp(*this);*this += 1;return tmp;}

测试:

3.2前置--和后置--的实现

与++的实现几乎一样,不再赘述

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

测试:

四、下期预告

内容有点多,博主就拆成两篇文章了,大概今晚发 

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

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

相关文章

计算机网络秋招面试题

自己在秋招过程中遇到的计算机网络的面试题 OSI七层网络模型 DNS&#xff1a;应用层协议 根据域名查IP地址 DNS查询⽅式有哪些&#xff1f; 递归解析 局部DNS服务器⾃⼰负责向其他DNS服务器进⾏查询&#xff0c;⼀般是先向该域名的根域服务器查询&#xff0c;再由根域名服…

【论文阅读笔记】Supervised Contrastive Learning

【论文阅读笔记】Supervised Contrastive Learning 摘要 自监督批次对比方法扩展到完全监督的环境中&#xff0c;以有效利用标签信息提出两种监督对比损失的可能版本 介绍 交叉熵损失函数的不足之处&#xff0c;对噪声标签的不鲁棒性和可能导致交叉的边际&#xff0c;降低了…

C语言真的需要头文件吗?

C语言真的需要头文件吗&#xff1f; 头文件的作用是什么&#xff1f; 如果你直接定义了函数&#xff0c;当然不需要头文件。 因为调用函数&#xff0c;你得知道函数的参数有多少&#xff0c;都什么类型的&#xff0c;返回值是什么&#xff0c;这样才能调用。最近很多小伙伴找…

盘点3种Python网络爬虫过程中的中文乱码的处理方法

网络爬虫过程中三种中文乱码的处理方案&#xff0c;希望对大家的学习有所帮助 一、思路 其实解决问题的关键点就是在于一点&#xff0c;就是将乱码的部分进行处理&#xff0c;而处理的方案主要可以从两个方面进行出发。其一是针对整体网页进行提前编码&#xff0c;其二是针对…

Java学习之路 —— 网络通信

文章目录 1. InetAddress2. UDP3. TCP4. 总结 1. InetAddress InetAddress的常用方法如下&#xff1a; public class InetAddressDemo {public static void main(String[] args) throws Exception{// 1. 获取本机IP地址对象InetAddress ip1 InetAddress.getLocalHost();Sys…

电子学会2023年6月青少年软件编程(图形化)等级考试试卷(二级)真题,含答案解析

青少年软件编程(图形化)等级考试试卷(二级) 一、单选题(共25题,共50分) 1. 运行下列哪段程序,可以让狗狗走到木屋门口?( ) A.

VUE基础入门

一、VUE入门 1、环境准备 2、预备知识 3、实战演练 vue官网 Vue.js - 渐进式 JavaScript 框架 | Vue.js 基础语法&#xff0c;vue2和vue3区别不大&#xff0c;但是后面路由会有很大区别。 前期基础语法&#xff0c;我们通过链接的方式使用vue&#xff0c;后面会用npm进行安装…

【精选】HTML5最全知识点集合

HTML5简介与基础骨架 HTML5介绍 HTML5是用来描述网页的一种语言&#xff0c;被称为超文本标记语言。用HTML5编写的文件&#xff0c;后缀以.html结尾 HTML是一种标记语言&#xff0c;标记语言是一套标记标签。标签是由尖括号包围的关键字&#xff0c;例如&#xff1a;<html…

vite2.9.15版本不显示el-table致命问题

1.版本说明 说明&#xff1a;vite版本为2.9.15&#xff1b;element-ui版本为2.15.14。 2.不显示 3.降低elementui版本 说明&#xff1a;不兼容&#xff0c;降低elementui版本为2.8.2 npm i element-ui2.8.2 4.显示

SourceTree修改Git密码

SourceTree用的好好的&#xff0c;无奈公司隔段时间强制更改电脑密码。更改完成后SourceTree无法使用&#xff0c;重新输入密码。VS的nuget也是。查资料虽然也能比较快的解决&#xff0c;但是。。。。在此转载记录下。 1. 找到 SourceTree 配置文件所在目录 ‘userhosts’ 目录…

基于Vue+SpringBoot的厦门旅游电子商务预订系统 开源项目

项目编号&#xff1a; S 030 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S030&#xff0c;文末获取源码。} 项目编号&#xff1a;S030&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 景点类型模块2.2 景点档案模块2.3 酒…

【机器学习 | 假设检验】那些经常被忽视但重要无比的假设检验!! 确定不来看看?(附详细案例)

&#x1f935;‍♂️ 个人主页: AI_magician &#x1f4e1;主页地址&#xff1a; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 &#x1f468;‍&#x1f4bb;景愿&#xff1a;旨在于能和更多的热爱计算机的伙伴一起成长&#xff01;&#xff01;&…