C++ 日期类实现详解(第四部分)

C++ 日期类实现详解(第四部分)

10. 完整的测试程序

在实现了日期类的所有核心功能之后,编写一个完善的测试程序显得尤为重要。通过测试程序,我们可以验证日期类的所有功能是否按预期工作,包括日期的加减、比较、自增自减和日期差值计算等。

10.1 测试日期加法

在日期加法测试中,我们将测试将日期对象加上一定的天数,确保日期能够正确地进位(跨月、跨年)。

void TestDateAdd() {Date d1(2024, 4, 14);Date d2 = d1 + 30000;  // 给 d1 加上 30000 天cout << "Original Date: ";d1.Print();  // 输出 d1cout << "After Adding 30000 Days: ";d2.Print();  // 输出 d2Date d3 = d1 + 45;  // 加上45天cout << "After Adding 45 Days: ";d3.Print();  // 输出加上45天后的日期
}
  • 通过加上大于一年的天数(30000 天),验证跨月跨年的处理是否正确。
  • 通过加上较小的天数(45 天),验证月份内的进位处理。

10.2 测试日期减法

日期减法测试主要关注日期对象减去天数时的正确性,包括跨月跨年借位的处理。

void TestDateSubtract() {Date d1(2024, 4, 14);Date d3 = d1 - 5000;  // 减去5000天cout << "Original Date: ";d1.Print();  // 输出 d1cout << "After Subtracting 5000 Days: ";d3.Print();  // 输出 d3Date d4 = d1 - 60;  // 减去60天cout << "After Subtracting 60 Days: ";d4.Print();  // 输出减去60天后的日期
}
  • 测试通过减去大量的天数(如 5000 天),确保日期能够正确地向前跨年。
  • 测试减去较小的天数(如 60 天),验证借位到前一个月的情况。

10.3 测试日期差值计算

日期差值计算测试将验证两个日期之间相差的天数是否计算正确。

void TestDateDifference() {Date d1(2024, 4, 14);Date d2(2034, 4, 14);int diff = d1 - d2;  // 计算 d1 和 d2 的日期差值cout << "Difference between d1 and d2: " << diff << " days" << endl;diff = d2 - d1;  // 反向计算cout << "Difference between d2 and d1: " << diff << " days" << endl;
}
  • 测试两个不同日期之间的差值,确保差值的正负符号正确。
  • 使用相同的日期,测试差值为零的情况。

10.4 测试自增和自减

通过对日期对象进行自增和自减操作,验证日期的加减一天功能。

void TestDateIncrementDecrement() {Date d1(2024, 4, 14);// 前置自增Date d2 = ++d1;cout << "After ++d1: ";d1.Print();cout << "d2 (result of ++d1): ";d2.Print();// 后置自增Date d3 = d1++;cout << "After d1++: ";d1.Print();cout << "d3 (result of d1++): ";d3.Print();// 前置自减Date d4 = --d1;cout << "After --d1: ";d1.Print();cout << "d4 (result of --d1): ";d4.Print();// 后置自减Date d5 = d1--;cout << "After d1--: ";d1.Print();cout << "d5 (result of d1--): ";d5.Print();
}
  • 通过前置自增和后置自增,测试自增后的日期是否正确。
  • 通过前置自减和后置自减,测试自减后的日期是否正确。

10.5 测试流插入与提取

流插入与提取运算符的测试主要通过 cincout 进行输入输出操作,验证日期对象能否正确进行数据交互。

void TestDateIO() {Date d1;cout << "Enter a date (year month day): ";cin >> d1;  // 从输入流读取日期cout << "You entered: ";cout << d1;  // 输出读取的日期Date d2(2024, 4, 14);cout << "Predefined Date: " << d2;  // 输出预定义的日期
}
  • 使用 cin >> d1 从用户输入读取日期。
  • 使用 cout << d1 输出用户输入的日期,验证输入输出的流插入与提取操作是否正常工作。

11. 日期类的优化建议

在实现了所有功能并通过测试后,接下来我们来探讨一些优化建议,以进一步提升代码的效率与可读性。

11.1 避免重复计算

在日期加法和减法中,GetMonthDay() 函数可能被多次调用。例如,在处理跨月时,会多次计算当月的天数。为了优化这一过程,可以将月份天数缓存起来,减少重复计算。

优化代码示例:
Date& Date::operator+=(int day) {if (day < 0) {return *this -= -day;}_day += day;int daysInMonth = GetMonthDay(_year, _month);  // 缓存当前月份的天数while (_day > daysInMonth) {_day -= daysInMonth;++_month;if (_month == 13) {++_year;_month = 1;}daysInMonth = GetMonthDay(_year, _month);  // 进入新月份,重新获取天数}return *this;
}

通过缓存 daysInMonth,我们避免了每次循环都重新计算当月天数,提升了代码的效率。

11.2 使用 C++ 标准库的日期处理

C++ 标准库提供了 chrono 库,用于处理时间与日期。虽然本项目主要是为了练习 C++ 类的实现与运算符重载,但在实际开发中,利用标准库可以大大简化日期的处理。

使用 chrono 示例:
#include <chrono>
using namespace std::chrono;system_clock::time_point today = system_clock::now();

chrono 库支持更复杂的时间计算和日期处理,如果你的项目对时间精度要求较高,可以考虑使用该库。

11.3 运算符的复用

我们可以通过重用已经实现的运算符,来减少代码冗余。例如,比较运算符(如 <=>= 等)可以通过复用 <== 来实现,而不必重复书写复杂的逻辑。

bool Date::operator<=(const Date& d) const {return *this < d || *this == d;
}

通过重用已有的运算符,代码将更加简洁且容易维护。

11.4 使用常量(const)和引用(&

为了优化性能并确保数据的安全性,尽量使用常量(const)和引用(&)来传递对象。例如,我们可以将日期对象的比较运算符参数设置为 const&,避免不必要的拷贝操作。

bool Date::operator<(const Date& d) const {// 比较日期的逻辑
}

const 确保运算符不会修改参数对象,& 避免了创建临时副本带来的性能开销。


12. 总结

通过上述详细的测试与优化,我们确保了 Date 类的每个功能都能正常工作,并提高了代码的可读性与执行效率。在项目中,我们通过类的封装、运算符重载、友元函数的使用等,深入理解了 C++ 类与对象的核心概念。

希望本篇博客能帮助你更好地掌握

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

[git] github管理项目之环境依赖管理

导出依赖到 requirements.txt pip install pipreqs pipreqs . --encodingutf8 --force但是直接使用pip安装不了torch&#xff0c;需要添加源&#xff01;&#xff01; pip install -r requirements.txt -f https://download.pytorch.org/whl/torch_stable.htmlpython 项目中 …

Stable Diffusion绘画 | AI 图片智能扩充,超越PS扩图的AI扩图功能(附安装包)

来到「文生图」页面&#xff0c;输入固定的起手式提示词。 第1步&#xff0c;开启 ControlNet&#xff0c;将需要扩充的图片加载进来&#xff1a; 控制类型选择「Inpaint」&#xff0c;预处理器选择「inpaint_onlylama」&#xff0c;缩放模式选择「缩放后填充空白」&#xff1…

【数据结构】【链表代码】移除链表元素

移除链表元素 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* removeElements(struct ListNode* head, int val) { // 创建一个虚拟头节点&#xff0c;以处理头节点可能被删除的情况 struct…

代码随想录Day54

今天是国庆假期后的恢复做题的第一天&#xff0c;摆了那么久感觉还是有点没摆够哈哈哈哈&#xff01;今天两道题都是困难题&#xff0c;两道题都去看讲解了&#xff0c;感觉这两道题是高度相似的&#xff0c;接雨水用单调递增栈来做&#xff0c;柱状图中最大的矩形用单调递减栈…

tcp/ip、以太网、mqtt、modbus/tcp复习

1.osi参考模型 2. modbus是应用层报文传输协议&#xff0c;没有规定物理层&#xff0c;只规定了协议帧&#xff0c;但是定义了控制器能够认识和使用的消息结构&#xff0c;不管它们是经过何种网络进行通信的&#xff0c;具有很强的适应性。 一主多从&#xff0c;同一时间主机…

【动态规划-最长公共子序列(LCS)】力扣1035. 不相交的线

在两条独立的水平线上按给定的顺序写下 nums1 和 nums2 中的整数。 现在&#xff0c;可以绘制一些连接两个数字 nums1[i] 和 nums2[j] 的直线&#xff0c;这些直线需要同时满足&#xff1a; nums1[i] nums2[j] 且绘制的直线不与任何其他连线&#xff08;非水平线&#xff09…

Rethinking Graph Neural Networksfor Anomaly Detection

AAAI24 推荐指数 #paper/⭐⭐ (由于这个领域初读&#xff0c;因此给的推荐分可能不好) 个人总结&#xff1a; 其在半监督&#xff08;1%&#xff0c;40%&#xff09;的情况下&#xff0c;使用多通滤波器&#xff0c;将不同滤波器得到的特征拼接起来&#xff0c;来做分类&…

【Blender Python】2.结合Kimi生成

概述 结合Kimi这样的AI工具可以生成Blender Python代码&#xff0c;用来辅助生成一些或简单或复杂的图形。当然&#xff0c;出不出错这就不一定了。因为AI所训练的版本可能并不是Blender的最新版本&#xff0c;类似的问题也出现在Godot上。 测试 在kimi中提问&#xff0c;获…

2024/10/6周报

文章目录 摘要Abstract广西的一些污水处理厂工艺解析1. A/O工艺&#xff08;厌氧-缺氧-好氧工艺&#xff09;2. 氧化沟工艺3. MBR工艺&#xff08;膜生物反应器&#xff09;4. SBR工艺&#xff08;序批式活性污泥法&#xff09;5. 生物接触氧化法 其它补充一体化改良氧化沟工艺…

LeetCode讲解篇之1143. 最长公共子序列

文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 这题我们可以采用动态规划求解&#xff0c;用一个二维数组记录text1的0 ~ i区间子串和text2的0 ~ j区间子串的最长公共子序列的长度&#xff0c;我们假设该二维数组是f 这个数组有一个特性&#xff0c;如果a <…

会议时如何实现扫码签到?

如何实现扫码签到&#xff1f; 在现代活动管理中&#xff0c;签到环节是不可或缺的一部分。它不仅关系到活动的顺利进行&#xff0c;还涉及到参与者的体验。传统的签到方式往往耗时且效率不高&#xff0c;而随着技术的发展&#xff0c;扫码签到成为了一种高效且便捷的解决方案。…

如何在算家云搭建CosyVoice(文生音频)

一、CosyVoice简介 CosyVoice 是一个开源的超强 TTS&#xff08;‌文本转语音&#xff09;‌模型&#xff0c;‌它支持多种生成模式&#xff0c;‌具有极强的语音自然可控性。‌ 具有以下特点&#xff1a; 语音合成 &#xff1a;能够将文本转换为自然流畅的语音输出。多语种…

redis——哨兵机制

redis中提供了哨兵&#xff08;Sentinel&#xff09;机制来实现主从集群的自动故障恢复。 主从复制是实现redis高可用性的基石&#xff0c;从节点宕机时我们仍然可以将请求发送给主节点或者其他从节点&#xff0c;而当主节点宕机的时候&#xff0c;无法执行写操作&#xff0c;无…

百元头戴式耳机都有哪些值得入手?四款爆款高性价比机型推荐

在追求性价比的时代&#xff0c;选择一款既实惠又高品质的头戴式降噪耳机&#xff0c;成为了许多人的明智之举。它不仅能够为您带来出色的音质和降噪效果&#xff0c;还能让您在享受音乐的同时&#xff0c;节省不必要的开支。那百元头戴式耳机都有哪些值得入手&#xff1f;让我…

Mysql备份与恢复——日志

Mysql日志 Buffer Pool Innodb 存储引擎设计了一个缓冲池&#xff08;Buffer Pool&#xff09;&#xff0c;来提高数据库的读写性能。 Mysql中比较重要的日志包括&#xff1a;二进制日志 binlog&#xff08;归档日志&#xff09;和 redo log&#xff08;重做日志&#xff09;…

【买瓜 / F】

题目 思路 折半搜索 注意要从小到大排序&#xff08;虽然我也不知道为什么&#xff09; 代码 #include <bits/stdc.h> using namespace std; typedef long long ll; int n, m, t; int a[35]; unordered_map<ll, int> h; int ans INT_MAX; void dfs1(int k, int…

系统架构设计师-论文题(2021年下半年)

1.试题一 论面向方面的编程技术及其应用针对应用开发所面临的规模不断扩大、复杂度不断提升的问题&#xff0c;面向方面的编程Aspect Oriented Programming,AOP技术提供了一种有效的程序开发方法。为了理解和完成一个复杂的程序&#xff0c;通常要把程序进行功能划分和封装。一…

54.二叉树的最大深度

迭代 class Solution {public int maxDepth(TreeNode root) {if(rootnull){return 0;}int de0;Queue<TreeNode> qunew LinkedList<>();TreeNode tn;int le;qu.offer(root);while(!qu.isEmpty()){lequ.size();while(le>0){tnqu.poll();if(tn.left!null){qu.offe…

【Linux】Ubuntu20.04上使用RabbitVCS的图形化SVN

文章目录 1、RabbitVCS1.1、RabbitVCS 介绍1.2、RabbitVCS 主要功能1.3、Ubuntu下 TortoiseSVN 替代者 2、安装2.1、命令安装2.2、安装使用2.3、使用权限 3、解决SVN无法保存密码问题3.1、问题描述3.2、解决方法 1、RabbitVCS 1.1、RabbitVCS 介绍 它是一款Linux系统下的图形…