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.mzph.cn/news/147414.shtml

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

相关文章

(带教程)商业版SEO关键词按天计费系统:关键词排名优化、代理服务、手机自适应及搭建教程

源码简介&#xff1a; 1、会员管理&#xff1a; 该系统分为三个级别的会员流程&#xff1a;总站管理员、代理与会员&#xff08;会员有普通会员、中级会员和高级会员三个等级&#xff09;。总站管理员可以添加代理用户并为其充值余额&#xff0c;代理用户可以为普通用户充值余…

java 访问sqlserver 和 此驱动程序不支持jre1.8错误

sqlserver数据如下&#xff1b; TestSQL.java&#xff1b; import java.sql.*;public class TestSQL {public static void main(String[] args) throws ClassNotFoundException, SQLException {String driverName "com.microsoft.sqlserver.jdbc.SQLServerDriver";…

[ATC复盘] abc329 20231118

[ATC复盘] abc329 20231118 总结A - Spread1. 题目描述2. 思路分析3. 代码实现 B - Next1. 题目描述2. 思路分析-3. 代码实现 C - Count xxx1. 题目描述2. 思路分析3. 代码实现 D - Election Quick Report2. 思路分析3. 代码实现 E - Stamp2. 思路分析3. 代码实现 F - Colored…

git基本操作(配图超详细讲解)

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 目录 创建git本地仓库 配置仓库 认识工作区&#xff0c;暂存区&#xff0c;版本库 修改文件 版本回退 撤销修改 删除文件 创建git本地仓库 要提前说的是&#xff0c;仓库是进⾏版本控制的⼀个⽂件⽬录。我们要想对⽂…

内网穿透的应用-通过内网穿透快速搭建公网可访问的Spring Boot接口调试环境

文章目录 前言1. 本地环境搭建1.1 环境参数1.2 搭建springboot服务项目 2. 内网穿透2.1 安装配置cpolar内网穿透2.1.1 windows系统2.1.2 linux系统 2.2 创建隧道映射本地端口2.3 测试公网地址 3. 固定公网地址3.1 保留一个二级子域名3.2 配置二级子域名3.2 测试使用固定公网地址…

windows nodejs 15.0.0下载安装

下载 Node v15.0.0 (Current) | Node.js (nodejs.org) 下载地址 https://nodejs.org/dist/v15.0.0/node-v15.0.0-x64.msi 安装 双击运行 等待安装完成 确认安装成功 管理员运行cmd 查看版本号

数据结构初阶leetcodeOJ题(二)

目录 第一题 思路&#xff1a; 第二题 思路 第三题 描述 示例1 思路 总结&#xff1a;这种类似的题&#xff0c;都是用快慢指针&#xff0c;相差一定的距离然后输出慢指针。 第一题 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val…

工程化实战 - 前端AST(进阶)

###脚手架 *快速自动化搭建启动工具 目标: ####第一步:处理依赖 npm i path npm i chalk4.1.0 npm i fs-extra npm i inquirer8.2.2 npm i commander npm i axios npm i download-git-repo //ora easy-table figlet ####第二步:处理工程入口 ####3.加入命令交互 交互好帮手…

【计算机网络】TCP协议

文章目录 TCP协议TCP的结构TCP的特点 TCP如何保证可靠传输确认应答&#xff08;可靠机制&#xff09;超时重传&#xff08;可靠机制&#xff09;连接管理&#xff08;可靠机制&#xff09;滑动窗口&#xff08;效率机制&#xff09;流量控制&#xff08;可靠机制&#xff09;拥…

window系统vscode 编译wvp前端代码

下载代码 wvp-GB28181-pro: WEB VIDEO PLATFORM是一个基于GB28181-2016标准实现的网络视频平台&#xff0c;负责实现核心信令与设备管理后台部分&#xff0c;支持NAT穿透&#xff0c;支持海康、大华、宇视等品牌的IPC、NVR、DVR接入。支持国标级联&#xff0c;支持rtsp/rtmp等…

zsh和ohmyzsh安装指南+插件推荐

文章目录 1. 安装指南2. 插件配置指南3. 参考信息 1. 安装指南 1. 安装 zsh sudo apt install zsh2. 安装 Oh My Zsh 国内访问GitHub sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"这将安装 Oh My Zsh 和所…

Xrdp+Cpolar实现远程访问Linux Kali桌面

XrdpCpolar实现远程访问Linux Kali桌面 文章目录 XrdpCpolar实现远程访问Linux Kali桌面前言1. Kali 安装Xrdp2. 本地远程Kali桌面3. Kali 安装Cpolar 内网穿透4. 配置公网远程地址5. 公网远程Kali桌面连接6. 固定连接公网地址7. 固定地址连接测试 前言 Kali远程桌面的好处在于…

从傅里叶变换,到短时傅里叶变换,再到小波分析(CWT),看这一篇就够了(附MATLAB傻瓜式实现代码)

本专栏中讲了很多时频域分析的知识&#xff0c;不过似乎还没有讲过时频域分析是怎样引出的。 所以本篇将回归本源&#xff0c;讲一讲从傅里叶变换→短时傅里叶变换→小波分析的过程。 为了让大家更直观得理解算法原理和推导过程&#xff0c;这篇文章将主要使用图片案例。 一…

数据结构第四课 -----线性表之栈

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

C_12练习题

一、单项选择题(本大题共20小题,每小题2分&#xff0c;共40分。在每小题给出的四个备选项中&#xff0c;选出一个正确的答案&#xff0c;并将所选项前的字母填写在答题纸的相应位置上。) C 风格的注释&#xff0c;也称块注释或多行注释&#xff0c;以&#xff08;&#xff09;…

软件开发、网络空间安全、人工智能三个方向的就业和前景怎么样?哪个方向更值得学习?

软件开发、网络空间安全、人工智能这三个方向都是当前及未来的热门领域&#xff0c;每个领域都有各自的就业前景和价值&#xff0c;以下是对这三个方向的分析&#xff1a; 1、软件开发&#xff1a; 就业前景&#xff1a;随着信息化的加速&#xff0c;软件开发的需求日益增长。…

SVG的viewBox、width和height释义, 示例及代码

svg的是没有边界的&#xff0c;svg画布只是用于展示svg世界中某一个范围的内容&#xff0c;而对于超过了svg画布范围的内容&#xff0c;则会被遮挡。默认svg画布默认显示世界坐标下原点坐标的width*height面积的矩形视野。 ​ 我们可以通过viewBox来修改默认的显示配置&#…

CAS源码工程搭建记录

CAS源码工程搭建 1.下载2.gradle下载源改为阿里云&#xff0c;解决下载慢的问题3.解决保存 1.下载 git clone -b 5.3.x https://gitee.com/mirrors/CAS.git如果下载的是压缩包&#xff0c;导入工程会保存&#xff0c;因为builder.gradle的第20行开始有取git信息&#xff0c;如…

实战提升(六)

前言&#xff1a;Practice makes perfect&#xff01;今天实战Leetcode链表分割还有回文结构。今天的题全都来自于牛客网。 实战一&#xff1a; 思路&#xff1a;我们一这个链表为例&#xff0c;小于5的链表尾插到第一个链表&#xff0c;大于5的链表尾插到第二个链表&#xf…

React升级到18版本

前言 升级前react版本是16.9.0&#xff0c;react-dom版本为16.9.0&#xff0c;react-router-dom为5.1.2版本。 安装 // npm npm install react react-dom// yarn yarn add react react-dom// pnpm pnpm install react react-dom启动项目 此时&#xff0c;项目可以正常运行&…