C++日期类详解 第二级支线任务
日期类的整体
class Date
{
public:// 构造函数Date(int year = 0, int month = 1, int day = 1);// 打印函数void Print() const;// 日期+=天数Date& operator+=(int day);// 日期+天数Date operator+(int day) const;// 日期-=天数Date& operator-=(int day);// 日期-天数Date operator-(int day) const;// 前置++Date& operator++();// 后置++Date operator++(int);// 前置--Date& operator--();// 后置--Date operator--(int);// 日期的大小关系比较bool operator>(const Date& d) const;bool operator>=(const Date& d) const;bool operator<(const Date& d) const;bool operator<=(const Date& d) const;bool operator==(const Date& d) const;bool operator!=(const Date& d) const;// 日期-日期int operator-(const Date& d) const;// 析构,拷贝构造,赋值重载可以不写,使用默认生成的即可private:int _year;int _month;int _day;
};
上述代码表示了这次要实现的类,包括了多种运算符的重载,以及构造函数,相似的操作符,我们只实现一个。
日期类的析构和拷贝赋值函数不用写用默认的,因为日期类用的都是内置类型,没有动态开辟的空间,所以不用考虑深拷贝的问题
构造函数
// 获取某年某月的天数
inline int getmonthday(int year, int month)
{// 数组存储平年每个月的天数static int dayArray[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };int day = dayArray[month];if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))){//闰年2月的天数day = 29;}return day;
}
// 构造函数
Date::Date(int year, int month, int day)
{// 检查日期的合法性if (year >= 0&& month >= 1 && month <= 12&& day >= 1 && day <= getmonthday(year, month)){_year = year;_month = month;_day = day;}else{// 严格来说抛异常更好cout << "非法日期" << endl;cout << year << "年" << month << "月" << day << "日" << endl;exit(1);}
}
上述代码解析:
一.getmonthday:这个函数用来判断是哪一年的哪一个月有几天
细节:
1.用static或者全局变量开辟dayArray[13],好处在于:节省每次调用函数时重复制造dayArray[13]。
2.inline内联函数,因为在Date对象进行++ -- 还有构造函数等多个函数都要用到getmonthday,所以用内联在调用的地方直接展开,省去了调用函数时找地址的时间消耗。
二.构造函数:构造函数很简单,但对于日期而言,每个月没有32天,没有13月,所以在构造函数要对传入的参数进行审批。错了以后直接exit退出。
operator+=和operator-=
为什么二者要一起讲,因为可以二者可以复用。
+=
// 日期+=天数
Date& Date::operator+=(int day)
{if (day<0){// 复用operator-=*this -= -day;}else{_day += day;// 日期不合法,通过不断调整,直到最后日期合法为止while (_day > GetMonthDay(_year, _month)){_day -= GetMonthDay(_year, _month);_month++;if (_month > 12){_year++;_month = 1;}}}return *this;
}
对于上述代码:为什么负数时我们复用-=,因为负数时,我们的日期是减法,但是在加等的逻辑中我们只考虑通过加法去改变日期,所以只考虑日期超限制的情况,如果减法倒退超过限制,我们不用单独写逻辑,而是直接复用-=的逻辑即可。
-=
// 日期-=天数
Date& Date::operator-=(int day)
{if (day < 0){// 复用operator+=*this += -day;}else{_day -= day;// 日期不合法,通过不断调整,直到最后日期合法为止while (_day <= 0){_month--;if (_month == 0){_year--;_month = 12;}_day += GetMonthDay(_year, _month);}}return *this;
}
对于上述代码:和+= 相同,-=只考虑下限不考虑上限。所以负数时复用+=。
记住:减法考虑下限,加法考虑上限,负数考虑复用
operator+
// 日期+天数
Date Date::operator+(int day) const
{Date tmp(*this);// 拷贝构造tmp,用于返回// 复用operator+=tmp += day;return tmp;
}
对于上述代码:
1.我们复用了+= 。
2.为什么要用拷贝构造:参考int 时的加法;如果只是单纯的+1那对i并不影响,而如果是将i + 1赋值给i 那才会对 i 造成影响。所以拷贝构造出一份新的对象,返回这个新对象。而不是在原对象上更改
int i = 0; i+1; i = i + 1;
operator- 和 + 同理。
前置++和后置++
和内置类型一样,前置++返回的是修改后的内容,后置++修改值,但是返回的是没++的内容。
前置++
// 前置++
Date& Date::operator++()
{// 复用operator+=*this += 1;return *this;
}
可以看到我们之间返回了*this,并且直接更改的*this。
后置++
// 后置++
Date Date::operator++(int)
{Date tmp(*this);// 拷贝构造tmp,用于返回// 复用operator+=*this += 1;return tmp;
}
后置++因为我们要返回的值是修改前的,所以我们拷贝构造后返回tmp,但不能引用!!!局部变量后续会销毁,但是传值传出去的是复制体,所以要用传值返回
前置--和后置--同理。
比较运算符
operator==
这里以==为例,其他的符号只是逻辑不同但是代码是类似的。
但值得一提的有:>= 可以复用 operator> 和 operator==. <= 同理。
bool Date::operator==(const Date& d) const
{return _year == d._year&&_month == d._month&&_day == d._day;
}
把该判断的都判断了就对了。
日期-日期
日期类的计算难点就在于,日期的进位,但是对于日期相减是有一个取巧的方法滴。
日期-日期,算天数,我们可以找到较大的日期,然后用较小的日期一直+1,直到 == 较大的日期。中间在用一个变量一直计算+了多少个1.就可以实现了。
// 日期-日期
int Date::operator-(const Date& d) const
{Date max = *this;// 假设第一个日期较大Date min = d;// 假设第二个日期较小int flag = 1;// 此时结果应该为正值if (*this < d){// 假设错误,更正max = d;min = *this;flag = -1;// 此时结果应该为负值}int n = 0;// 记录所加的总天数while (min != max){min++;// 较小的日期++n++;// 总天数++}return n*flag;
}
相关文章:
C++日期类详解 第二级支线任务
日期类的整体 class Date { public:// 构造函数Date(int year 0, int month 1, int day 1);// 打印函数void Print() const;// 日期天数Date& operator(int day);// 日期天数Date operator(int day) const;// 日期-天数Date& operator-(int day);// 日期-天数Date …...
java--通用启动/停止shell脚本
脚本 #!/bin/bash# 定义超时时间(秒) timeout10# 检查命令参数 case "$1" instart|stop|restart|help)action"$1"jar_file"$2";;*)echo "Usage: $0 {start|stop|restart|help} [jar_file]"exit 1;; esac# 定义…...
Flutter-底部选择弹窗(showModalBottomSheet)
前言 现在有个需求,需要用底部弹窗来添加定时的重复。在这里使用原生的showModalBottomSheet来实现 showModalBottomSheet的Props 名称 描述 isScrollControlled全屏还是半屏isDismissible外部是否可以点击,false不可以点击,true可以点击&a…...
Linux——k8s认识
计算资源隔离 - 更方便进行高并发架构的维护和升级 - 架构管理的灵活性更高,不再以单个节点的物理资源作为基础 技术: - 硬件辅助虚拟化 - 容器技术 在企业部署方案中,很少以单节点实现虚拟化和容器技术,一般以集群状态来运…...
EC Shop安装指南 [ Apache PHP Mysql ]
这个是软件测试课上老师布置的一个作业,期间老师也出现了不少错误,所以还是有必要记录一下吧,凑一篇文章 主要是老师的文档以及自己的一些尝试记录,试错记录,解决方案等 主要介绍了Apache的安装,MySQL的安…...
无线感知会议系列【3】【基于WiFi和4G/5G的非接触无线感知:挑战、理论和应用-1】
前言: 2020年北京智源大会 张大庆老师的一个报告 参考链接: 基于WiFi和4G/5G的非接触无线感知:挑战、理论和应用_哔哩哔哩_bilibili 目录: 无线感知简介 无线感知的核心 研究方向 Frsenel 模型 基于Fresnel 感知的应用举例…...
Virtuoso服务在centos中自动停止的原因分析及解决方案
目录 前言1. 问题背景2. 原因分析2.1 终端关闭导致信号12.2 nohup命令的局限性 3. 解决方案3.1 使用 screen 命令保持会话3.2 使用 tmux 作为替代方案3.3 使用系统服务(systemd) 4. 其他注意事项4.1 网络配置4.2 日志监控 结语 前言 在使用Virtuoso作为…...
泽众P-One性能测试平台火焰图帮助定位产品性能问题
在软件开发过程中,性能问题往往是最头疼的问题之一。随着软件系统的日益复杂,快速准确地定位并解决性能问题变得尤为重要。泽众P-One作为一站式性能测试平台,通过引入火焰图性能分析可视化工具,极大地提升了性能问题的定位效率和解…...
数据结构修炼——顺序表和链表的区别与联系
目录 一、线性表二、顺序表2.1 概念及结构2.2 接口实现2.3 一些思考以及顺序表的缺点 三、链表3.1 概念及结构3.2 链表的分类3.3 链表的实现3.3.1 无头单向非循环链表3.3.2 带头双向循环链表 四、顺序表和链表的区别 一、线性表 线性表(linear list)是n…...
AD9854 为什么输出波形幅度受限??
🏆本文收录于《全栈Bug调优(实战版)》专栏,主要记录项目实战过程中所遇到的Bug或因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&am…...
在grafana上配置显示全部node资源信息概览
在grafana上配置显示全部node资源信息概览,便于巡检 1,注册grafana官网账号:Grafana dashboards | Grafana Labs 2、寻找可以展示所有node资源概览信息的dashboard,并下载支持prometheus数据源的dashboardÿ…...
MySQL —— 索引
索引的概念 MySQL的索引是⼀种数据结构,它可以帮助数据库高效地查询、更新数据表中的数据。索引通过 ⼀定的规则排列数据表中的记录,使得对表的查询可以通过对索引的搜索来加快速度。 MySQL索引类似于书籍的目录,通过指向数据行的位置&…...
(已解决)vscode如何选择python解释器
文章目录 前言解决方案 前言 有的时候可能有不同版本的编译器,以适用不同年份的项目。所以,怎么在vscode中换python解释器呢? 解决方案 对着要运行的python文件进行右键,比如我是要运行main文件,点击那个命令选项版…...
sql刷题常用函数
ROW_NUMBER() ROW_NUMBER() OVER (PARTITION BY ... ORDER BY ...) 是一个窗口函数,用于生成每个分组内的唯一行号。这个函数非常适合在分组数据中进行排序,并为每一行分配一个序号。下面是对你的具体示例的详细解释: ROW_NUMBER() OVER (…...
Golang | Leetcode Golang题解之第417题太平洋大西洋水流问题
题目: 题解: type pair struct{ x, y int } var dirs []pair{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}func pacificAtlantic(heights [][]int) (ans [][]int) {m, n : len(heights), len(heights[0])pacific : make([][]bool, m)atlantic : make([][]bool, …...
Acwing Hash表
哈希表的作用:把一个比较大的空间,通过一个函数映射到一个比较小的空间 一般做哈希运算时,取一个质数作为模,会使得冲突的概率降低。 哈希表的冲突解决方法: 拉链法开放寻址法 下面详细介绍这两种方法的原理及其实现…...
大健康裂变分销小程序开发
大健康裂变分销小程序的开发是一个涉及技术、市场策略、用户体验和合规性等多个方面的综合项目。这类小程序旨在通过分销机制促进大健康产品的销售和品牌推广,同时利用社交网络的裂变效应扩大市场影响力。以下是大健康裂变分销小程序开发的主要步骤和考虑因素&#…...
js取出一个对象中指定的字段(封装公共方法)
需求:在一个对象里面挑选出所需要的一个或多个字段 例子:在{ a: 1, b: 2, c: 3, d: 4 }里面挑选出b和d字段 封装公共方法 const pick (obj, keys) > {return Object.keys(obj).filter(key > keys.includes(key)).reduce((result, key) > {if …...
【黑马点评】已解决java.lang.NullPointerException异常
Redis学习Day3——黑马点评项目工程开发-CSDN博客 问题发现及描述 在黑马点评项目中,进行到使用Redis提供的Stream消息队列优化异步秒杀问题时,我在进行jmeter测试时遇到了重大的错误 发现无论怎么测试,一定会进入到catch中,又由…...
计算机专业的就业方向
计算机专业的就业方向 亲爱的新生们,欢迎你们踏上计算机科学的旅程!作为一名计算机专业的学生,你们即将进入一个充满无限可能的领域。今天,我将为大家介绍计算机专业的一些主要就业方向,帮助你们了解未来的职业选择。…...
如何免费解锁百度网盘SVIP下载:Mac版终极加速指南
如何免费解锁百度网盘SVIP下载:Mac版终极加速指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘缓慢的下载速度而烦恼吗&a…...
PyTorch-CUDA-v2.7镜像应用场景:快速启动AI模型训练与推理
PyTorch-CUDA-v2.7镜像应用场景:快速启动AI模型训练与推理 1. 镜像概述与核心优势 PyTorch-CUDA-v2.7镜像是一个开箱即用的深度学习环境解决方案,专为需要快速启动AI模型训练与推理的开发者设计。这个预配置的Docker镜像集成了PyTorch 2.7框架和完整的…...
文墨共鸣模型与SolidWorks设计文档交互:基于文本的产品设计需求分析
文墨共鸣模型与SolidWorks设计文档交互:基于文本的产品设计需求分析 你有没有过这样的经历?脑子里有一个新产品的绝妙想法,或者客户给了一堆模糊的功能描述,但当你坐在SolidWorks面前,准备把这些想法变成三维模型时&a…...
OpenClaw调试技巧:解决SecGPT-14B模型返回结果异常问题
OpenClaw调试技巧:解决SecGPT-14B模型返回结果异常问题 1. 问题背景与现象描述 上周在尝试用OpenClaw对接SecGPT-14B模型时,遇到了一个棘手的问题:模型返回的结果经常出现截断或格式混乱。具体表现为: 当请求生成网络安全报告时…...
OpenClaw+Qwen2.5-VL-7B:个人社交媒体自动化图文创作
OpenClawQwen2.5-VL-7B:个人社交媒体自动化图文创作 1. 为什么选择OpenClaw做社交媒体自动化 去年我开始运营一个科技类自媒体账号,最初每天花3小时手动找素材、写文案、配图。直到发现OpenClaw这个开源框架,我的工作流彻底改变了——现在9…...
如何在不同的机器上运行多个OpenClaw实例?
想让不同机器上的 OpenClaw 一起协作,其实就是搭建一个跨机器的 “小龙虾通信网络”。实现方式分两种:简单直连(适合测试 / 小集群)和远程网关(适合生产 / 稳定协作)。下面给你一套直接能跑的完整方案。一、…...
嵌入式Linux设备可靠升级方案设计与实践
1. 嵌入式Linux升级方案概述在嵌入式Linux设备开发中,软件升级是一个永恒的话题。作为一名嵌入式开发工程师,我经历过无数次凌晨三点被叫起来处理升级失败的痛苦经历。经过多年实践,我总结出一套同时支持本地和远程升级的可靠方案,…...
BD663474车载LCD驱动芯片技术解析与CARIAD集成实践
1. BD663474驱动芯片技术解析:面向CARIAD车载显示系统的TFT-LCD底层控制实现BD663474是ROHM半导体推出的一款专为汽车级TFT-LCD面板设计的源极驱动(Source Driver)与栅极驱动(Gate Driver)集成控制器,广泛应…...
LPD8806驱动库详解:SPI控制16位PWM LED灯带的嵌入式实践
1. LPD8806驱动库技术解析:面向嵌入式系统的PWM LED控制器深度实践1.1 芯片定位与工程价值LPD8806是凌阳(Sunplus)推出的16位恒流LED驱动IC,专为高密度RGB LED灯带、像素点阵及舞台灯光系统设计。其核心价值在于以极低成本实现精确…...
国央企创新负责人如何实现科技成果与产业需求的精准对接?
观点作者:科易网-国家科技成果转化(厦门)示范基地 一、现状概述:成效与短板 在“数智产品共享空间”助力下,国央企在科技成果转化方面已取得显著成效。通过构建智能化服务平台,部分央企已在数字化转型中走在…...
