C++日期类的基本实现
前言
对于许多出初学C++的同学来说首先接触的第一个完整的类便是日期类,这个类能有效的帮助我们理解C++中有关类的初始化以及重载的相关知识,帮助我们轻松上手体验C++的魅力。
文章目录
- 前言
- 一、日期类整体初概
- 二、构造
- 2.1 判断日期是否合法
- 2.2 构造函数
- 三、关系判断
- 3.1 大于(>)运算符
- 3.2 等于(=)运算符
- 3.3 其余运算符重载
- 四、日期的加减运算
- 4.1 +/+=运算符
- 4.2 -/-=运算符
- 4.3 日期相减
- 4.4 推算当日星期
- 五、前置++与后置++运算符
- 5.1 前置++运算符
- 5.2 后置++运算符
- 六、流插入和流提取操作符重载
一、日期类整体初概
完成一个类,我们首先需要了解这个类需要完成什么任务,需要哪些函数来进行实现,以下是一个日期类的模板框架。
class Date
{//检查日期合法bool CheckDate();//获取每月天数int GetMonthDay(int year, int month);//构造函数Date(int year = 1900, int month = 1, int day = 1);//关系判断操作符重载bool operator>(const Date& d1);bool operator== (const Date& d2);bool operator>=(const Date& d1);bool operator<(const Date& d1);bool operator<=(const Date& d1);bool operator!=(const Date& d1);//日期类的加减操作Date& operator +=(int day);Date operator +(int day);Date& operator-=(int day);Date operator-(int day);//日期减去日期int operator- (const Date& d);//计算当前天数为星期几void WeekDay();//前置、后置操作符Date& operator++();Date operator++(int);Date& operator--();Date operator--(int);//流插入和流提取操作符重载friend ostream& operator<<(ostream& out, const Date& d);friend istream& operator>>(istream& in, Date& d);
};
二、构造
在确认基本框架后,第一步是为我们的自定义类创建一个合适的构造函数,对于日期类而言,我们则需要在最开始实例化类的时候对日期进行一个判断,判断日期的合法性,例如年份大于1,月份在1-12之间,天数在对于的月份天数之内,具体的是实现如下:
2.1 判断日期是否合法
//获取当前月份的日期
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;
}// 检查日期是否合法
bool CheckDate()
{if (_year < 1 || _month>13 || _month < 1 || _day<1 || _day>GetMonthDay(_year, _month))return false;return true;
}
2.2 构造函数
Date(int year=1900,int month=1,int day=1){_year = year;_month = month;_day = day;//检查生成的日期是否非法if (!CheckDate()){cout << "日期非法:" ;Print();//退出程序,正常退出exit(0),非法退出exit(非0);exit(-1);}}
三、关系判断
3.1 大于(>)运算符
bool operator>(const Date& d1)
{if ((_year > d1._year)|| (_year >= d1._year && _month > d1._month)|| (_year >= d1._year && _month >= d1._month && _day > d1._day)){return true;}return false;
}
3.2 等于(=)运算符
bool operator== (const Date& d2)
{return _year == d2._year&& _month == d2._month&& _day == d2._day;
}
3.3 其余运算符重载
在上面我们实现了 > 、 = 两个运算符重载。为了方便和提高可读性,对于剩下的>=、< 、 <= 、!= 这四个运算符我们可以复用的方式实现,利用> 、 = 两个运算符的逻辑组合来进行实现。
bool operator>=(const Date& d1)
{return (*this > d1) || (*this == d1);
}bool operator<(const Date& d1)
{return !(*this >= d1);
}bool operator<=(const Date& d1)
{return !(*this > d1);
}bool operator!=(const Date& d1)
{return !(*this == d1);
}
四、日期的加减运算
4.1 +/+=运算符
思路上我们选择一个日期加上具体天数之后,采取逐一加天数的方式,每次加完之后进行判断,当前天数是否大于当月天数,同时当月数进一的时候判断当前月数是否大于十二,依次进位。
Date operator +(int day)
{//如果day 是负数 调用-操作符重载if (day < 0){return *this - (-day);}Date d1(*this);//直接加到_day上,直到_day合法。d1._day += day;while (d1._day > GetMonthDay(d1._year, d1._month)){d1._day -= GetMonthDay(d1._year, d1._month);++d1._month;if (d1._month == 13){d1._month = 1;d1._year++;}}return d1;
}// 直接复用 "+" 运算符即可
Date& operator +=(int day)
{*this = *this + day;return *this;
}
4.2 -/-=运算符
思路上和日期加天数是一样的,但是不同的地方在于,当前天数小于1时,我们采取月份减一的方式,依次借位。
Date& operator-=(int day)
{//如果减去负天数 ,则调用 +=if (day < 0){return *this += -day;}//直接减去_day -= day;//借位减去天数,直到天数合法while (_day <= 0){--_month;if (_month == 0){--_year;_month = 12;}//加上天数_day += GetMonthDay(_year, _month);}return *this;
}// 复用顺序不重要
Date operator-(int day)
{Date temp(*this);temp -= day;return temp;
}
4.3 日期相减
我们在上面已经实现了日期加上天数以及两个日期之间是否相等的判断,在此可以直接复用,默认前一个日期大于后一个日期,将较小的日期天数逐次加一,当加到和较大天数相等时,此时加一的次数就是日期之间相差的天数。
//两个日期相减
int operator- (const Date & d)
{//先假设 *this > dint flag = 1;Date max = *this;Date min = d;if (*this < d){max = d;min = *this;flag = -1;}int count = 0;while (min != max){ ++min;++count;}return count * flag;
}
4.4 推算当日星期
由于1900年1月1日正好是周一,因此我们计算某个日期减去1900年1月1日得到的天数并对七取模即可。
//判断当前日期是周几
void WeekDay( )
{Date statr(1900, 1, 1);//求相差的天数int n = *this - statr;//5相当于是周6int weekday = 0;weekday += n;cout << "周" << weekday % 7 + 1 << endl;
}
五、前置++与后置++运算符
对于前置++和后置++运算符两者之间似乎操作数一样,但是不同之处在于后置++重载时有一个操作数,同时需要注意后置++运算符返回值应是修改前的值,对于 “–” 运算符与 “++“ 运算符基本一致,不在此列出。
5.1 前置++运算符
Date& operator++()
{return *this += 1;
}
5.2 后置++运算符
Date operator++(int)
{Date temp(*this);*this += 1;return temp;
}
六、流插入和流提取操作符重载
相比于其他的运算符,流插入和流提取则有一丝不同,我们知道运算符重载时默认第一位是 this 指针,但是流插入和流提取第一个操作数明显是流插入运算符或流提取运算符,因此必须将其设为全局函数。
此时又会遇到另一个问题,全局函数如何访问类的私有成员,此时就需提前将其声明为友元函数在进行重载。
ostream& operator<<(ostream& out,const Date& d)
{out << d._year << '/' << d._month << '/' << d._day;return out;
}istream& operator>>(istream& in, Date& d)
{in >> d._year >> d._month >> d._day;//检查输入格式是否正确assert(d.CheckDate());return in;
}
相关文章:
C++日期类的基本实现
前言 对于许多出初学C的同学来说首先接触的第一个完整的类便是日期类,这个类能有效的帮助我们理解C中有关类的初始化以及重载的相关知识,帮助我们轻松上手体验C的魅力。 文章目录 前言一、日期类整体初概二、构造2.1 判断日期是否合法2.2 构造函数 三、…...

第六章:数据结构与算法-part3:数据结构算法提升
文章目录 一、排序算法1.1 插入排序1、直接插入排序2、折半插入排序3、希尔排序 1.2、交换排序法1、起泡排序2、快速排序 1.3 选择类排序1、简单选择排序 二、业务逻辑算法设计2.1 基本概念和术语2.2 静态查找表2.3、有序表的查找 一、排序算法 排序是数据处理过程中经常使用的…...

keras深度学习框架通过卷积神经网络cnn实现手写数字识别
昨天通过keras构建简单神经网络实现手写数字识别,结果在最后进行我们自己的手写数字识别的时候,准确率堪忧,只有60%。今天通过卷积神经网络来实现手写数字识别。 构建卷积神经网络和简单神经网络思路类似,只不过这里加入了卷积、池…...

Springboot启动异常 Command line is too long
Springboot启动异常 Command line is too long Springboot启动时直接报异常 Command line is too long. Shorten command line for xxxxxApplication or also for Spring Boot default解决方案: 修改 SystemApplication 的 Shorten command line,选择 JAR manife…...

PXE 装机(五十)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一、PXE是什么 二、PXE的组件 三、配置vsftpd 四、配置tftp 五、准备pxelinx.0文件、引导文件、内核文件 六、配置dhcp 七、创建default文件 八、配置pxe无人值守…...
C++ 虚函数与纯虚函数
目录 1. 虚函数 2. 纯虚函数 C 中的虚函数和纯虚函数都是实现多态的重要机制。多态可以让不同的对象以相同的方式进行操作,从而简化代码的编写和维护。 1. 虚函数 虚函数是一种在基类中声明的函数,可以在派生类中进行重写。在运行时,根据对…...

警告:Provides transitive vulnerable dependency maven:org.yaml:snakeyaml:1.30
1. 警告 SpringBoot 的 validation 依赖包含有易受攻击的依赖 snakeyaml。 警告信息如下: Provides transitive vulnerable dependency maven:org.yaml:snakeyaml:1.30 意思是:提供了可传递的易受攻击依赖 maven:org.yaml:snakeyaml:1.30 2. 警告示例 …...

中文命名实体识别
本文通过people_daily_ner数据集,介绍两段式训练过程,第一阶段是训练下游任务模型,第二阶段是联合训练下游任务模型和预训练模型,来实现中文命名实体识别任务。 一.任务和数据集介绍 1.命名实体识别任务 NER(Named En…...

WPF CommunityToolkit.Mvvm Messenger通讯
文章目录 环境WeakReferenceMessenger方法介绍无回调订阅发送Token区分有回调订阅发送 环境 CommunityToolkit.Mvvm Messenger 十月的寒流: 如何使用 CommunityToolkit.Mvvm 中的 Messenger 来进行 ViewModel 之间的通信 WeakReferenceMessenger 我这里只讲简单的弱Messenger…...

【杂言】写在研究生开学季
这两天搬进了深研院的宿舍,比中南的本科宿舍好很多,所以个人还算满意。受台风 “苏拉” 的影响,原本的迎新计划全部打乱,导致我现在都还没报道。刚开学的半个月将被各类讲座、体检以及入学教育等活动占满,之后又是比较…...
渗透测试漏洞原理之---【任意文件读取漏洞】
文章目录 1、概述1.1、漏洞成因1.2、漏洞危害1.3、漏洞分类1.4、任意文件读取1.4.1、文件读取函数1.4.2、任意文件读取 1.5、任意文件下载1.5.1、一般情况1.5.2、PHP实现1.5.3、任意文件下载 2、任意文件读取攻防2.1、路径过滤2.1.1、过滤../ 2.2、简单绕过2.2.1、双写绕过2.2.…...

合宙Air724UG LuatOS-Air LVGL API控件-图片 (Image)
图片 (Image) 图片IMG是用于显示图像的基本对象类型,图像来源可以是文件,或者定义的符号。 示例代码 -- 创建图片控件 img lvgl.img_create(lvgl.scr_act(), nil) -- 设置图片显示的图像 lvgl.img_set_src(img, "/lua/luatos.png") -- 图片…...

仿京东 项目笔记2(注册登录)
这里写目录标题 1. 注册页面1.1 注册/登录页面——接口请求1.2 Vue开发中Element UI的样式穿透1.2.1 ::v-deep的使用1.2.2 elementUI Dialog内容区域显示滚动条 1.3 注册页面——步骤条和表单联动 stepsform1.4 注册页面——滑动拼图验证1.5 注册页面——element-ui组件Popover…...
Spark与Flink的区别
分析&回答 (1)设计理念 1、Spark的技术理念是使用微批来模拟流的计算,基于Micro-batch,数据流以时间为单位被切分为一个个批次,通过分布式数据集RDD进行批量处理,是一种伪实时。 2、Flink是基于事件驱动的,是面向流的处理框架, Flink基于…...

未来智造:珠三角引领人工智能产业集群
原创 | 文 BFT机器人 产业集群是指产业或产业群体在地理位置上集聚的现象,产业集群的研究对拉动区域经济发展,提高区域产业竞争力具有重要意义。 从我国人工智能产业集群形成及区域布局来看,我国人工智能产业发展主要集聚在京津冀、长三角、…...
【Unity db】sqlite
背景 最近使用unity,需要用到sqlite,记录下使用过程 需要的动态库 Mono.Data.Sqlite.dll,这个文件下载参考下面链接 SqliteConnection的Close和Open 连接的概念: 在数据库编程中,连接是一个重要的概念,…...

Linux 指令心法(四)`touch` 创建一个新的空文件
文章目录 命令的概述和用途命令的用法命令行选项和参数的详细说明命令的示例命令的注意事项或提示 命令的概述和用途 touch 是一个用于在 Linux 和 Unix 系统中创建空文件或更改现有文件的访问和修改时间的命令。如果指定的文件不存在,touch会创建一个新的空文件&a…...

分类算法系列②:KNN算法
目录 KNN算法 1、简介 2、原理分析 数学原理 相关公式及其过程分析 距离度量 k值选择 分类决策规则 3、API 4、⭐案例实践 4.1、分析 4.2、代码 5、K-近邻算法总结 🍃作者介绍:准大三网络工程专业在读,努力学习Java,涉…...

12. 微积分 - 梯度积分
Hi,大家好。我是茶桁。 上一节课,我们讲了方向导数,并且在最后留了个小尾巴,是什么呢?就是梯度。 我们再来回看一下但是的这个式子: [ f x f y...
Large Language Models and Knowledge Graphs: Opportunities and Challenges
本文是LLM系列的文章,针对《Large Language Models and Knowledge Graphs: Opportunities and Challenges》的翻译。 大语言模型和知识图谱:机会与挑战 摘要1 引言2 社区内的共同辩论点3 机会和愿景4 关键研究主题和相关挑战5 前景 摘要 大型语言模型&…...

使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...

七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

无人机侦测与反制技术的进展与应用
国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机(无人驾驶飞行器,UAV)技术的快速发展,其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统,无人机的“黑飞”&…...
tomcat入门
1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效,稳定,易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...
uniapp 实现腾讯云IM群文件上传下载功能
UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中,群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS,在uniapp中实现: 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...

echarts使用graphic强行给图增加一个边框(边框根据自己的图形大小设置)- 适用于无法使用dom的样式
pdf-lib https://blog.csdn.net/Shi_haoliu/article/details/148157624?spm1001.2014.3001.5501 为了完成在pdf中导出echarts图,如果边框加在dom上面,pdf-lib导出svg的时候并不会导出边框,所以只能在echarts图上面加边框 grid的边框是在图里…...
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ is not explicitly defined.
这个警告表明您在使用Vue的esm-bundler构建版本时,未明确定义编译时特性标志。以下是详细解释和解决方案: 问题原因: 该标志是Vue 3.4引入的编译时特性标志,用于控制生产环境下SSR水合不匹配错误的详细报告1使用esm-bundler…...

安宝特方案丨从依赖经验到数据驱动:AR套件重构特种装备装配与质检全流程
在高压电气装备、军工装备、石油测井仪器装备、计算存储服务器和机柜、核磁医疗装备、大型发动机组等特种装备生产型企业,其产品具有“小批量、多品种、人工装配、价值高”的特点。 生产管理中存在传统SOP文件内容缺失、SOP更新不及、装配严重依赖个人经验、产品装…...
rk3506上移植lvgl应用
本文档介绍如何在开发板上运行以及移植LVGL。 1. 移植准备 硬件环境:开发板及其配套屏幕 开发板镜像 主机环境:Ubuntu 22.04.5 2. LVGL启动 出厂系统默认配置了 LVGL,并且上电之后默认会启动 一个LVGL应用 。 LVGL 的启动脚本为/etc/init.d/pre_init/S00-lv_demo,…...

短视频时长预估算法调研
weighted LR o d d s T p 1 − p ( 1 − p ) o d d s T p ( T p o d d s ∗ p ) o d d s p o d d s T o d d s odds \frac{Tp}{1-p} \newline (1-p)odds Tp \newline (Tp odds * p) odds \newline p \frac{odds}{T odds} \newline odds1−pTp(1−p)oddsTp(Tpodds…...