C++ 日期类的实现

目录

前言

日期类中的成员函数和成员变量 

日期类中成员函数的详解和实现 

1.天数前后的判断

2.天数加减的实现

3.前置++ && 后置++

4.计算天数差值


前言

        日期类的实现将综合前面所学的(类的6个默认成员函数),进一步理解和掌握类的6个默认成员函数。

若对(类的6个成员函数不太理解)请先看前文:

C++ 类与对象(中)-CSDN博客

C++ 类与对象(中)续-CSDN博客


日期类中的成员函数和成员变量 

以下声明都在.h文件中

class Date
{
public://全缺省的构造函数Date(int year = 1, int month = 1, int day = 1);//运算符重载bool operator<(const Date& d);bool operator<=(const Date& d);bool operator>(const Date& d);bool operator>=(const Date& d);bool operator==(const Date& d);bool operator!=(const Date& d);// 天数的加减Date& operator+=(int day);Date operator+(int day);Date operator-(int day);Date& operator-=(int day);//前置++ 后置++Date& operator++();// 特殊处理:解决语法逻辑不自洽,自相矛盾的问题// d1++// 为了跟前置++区分,强行增加一个int形参,够成重载区分Date operator++(int);Date operator--(int);Date& operator--();// 天数-天数int operator-(const Date& d);// 本质就是inline(不声明和定义分离)//判断闰年还是平年int GetMonthDay(int year, int month){assert(month > 0 && month < 13);static int monthDays[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };// 365   自转  公转  365 5+h// 366if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))){return 29;}return monthDays[month];}void Print(){cout << _year << "/" << _month << "/" << _day << endl;}private:int _year;int _month;int _day;
};


日期类中成员函数的详解和实现 

1.天数前后的判断

这是 实现Date 类,对比较运算符 < 的重载定义。它比较两个 Date 对象,如果第一个日期早于第二个日期,则返回 true ,否则返回 false 。

以下是它的工作原理:

1. 它比较两个日期的年份。如果第一个日期的年份小于第二个日期的年份,则返回 true 。

2. 如果年份相等,则比较两个日期的月份。如果第一个日期的月份小于第二个日期的月份,则返回 true 。

3. 如果月份相等,则比较两个日期的天数。如果第一个日期的天数小于第二个日期的天数,则返回 true 。

4. 如果所有比较都为 false,则表示两个日期相等,因此返回 false 。

bool Date::operator<(const Date& d)
{if (_year < d._year){return true;}else if (_year == d._year){if (_month < d._month){return true;}else if (_month == d._month){if (_day < d._day){return true;}}}return false;
}

==运算符的实现,== 运算符通过比较 _year 、 _month 和 _day 来实现。如果三个成员变量都相等,则返回 true ,否则返回 false 。

bool Date::operator==(const Date& d)
{return _year == d._year&& _month == d._month&& _day == d._day;
}

<=运算符的实现,在上面我们实现了<和=连个运算符,在实现<=的时候我们就可以调用<和=运算符了。

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

>运算符的实现,在上面我们实现了<=运算符,那么对<=运算符取反就可以了。

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

>=运算符的实现,要得到>=那么我们只需要对<运算符取反。

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

天数前后判断函数的测试:

int main()
{Date d1(2024, 2, 3);Date d2(2024, 2, 1);cout << (d1 > d2) << endl;cout << (d1 < d2) << endl;cout << (d1 >= d2) << endl;cout << (d1 <= d2) << endl;
}


2.天数加减的实现

+=操作的实现,这个函数是 Date 类的成员函数,它将一个给定的天数添加到日期中。

它首先将给定的天数添加到 _day 中。然后,它检查 _day 是否大于该月的总天数。如果大于,则将 _day 减去该月的总天数,并将 _month 增加 1。如果 _month 等于 13,则将 _year 增加 1,并将 _month 重置为 1。

最后,它返回对当前对象的引用。

(注意:这里为什么是实现+=的操作,因为此时_day已经被改变,而+操作是不改变_day本身的)

Date& Date::operator+=(int day)
{_day += day;while (_day > GetMonthDay(_year, _month)){_day -= GetMonthDay(_year, _month);++_month;if (_month == 13){++_year;_month = 1;}}return *this;
}

+操作的实现,为了不修改当前对象_day,我们需要创建一个临时变量tmp,最后返回tmp的拷贝,实现+的操作。

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

接下来是-=和-操作的实现。

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

天数加减操作的测试:

int main()
{Date d1(2024, 2, 3);Date d2 = d1 + 20;d2.Print();d1.Print();d2 -= 20;d2.Print();d1 += 30000;d1.Print();
}

日期计算器的结果:


3.前置++ && 后置++

前置++:返回+1之后的结果
注意:this指向的对象函数结束后不会销毁,故以引用方式返回提高效率

Date& Date::operator++()
{*this += 1;return *this;
}

 后置++:
前置++和后置++都是一元运算符,为了让前置++与后置++形成能正确重载
     C++规定:后置++重载时多增加一个int类型的参数,但调用函数时该参数不用传递,编译器 自动传递
     注意:后置++是先使用后+1,因此需要返回+1之前的旧值,故需在实现时需要先将this保存一份,然后给this + 1,而temp是临时对象,因此只能以值的方式返回,不能返回引用

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

前置++ && 后置++的测试:

int main()
{Date d1(2024, 2, 3);++d1;d1.operator++();d1.Print();d1++;//此写法自动识别d1.operator++(0);//这种写法传参帮助编译器识别d1.Print();}


4.计算天数差值

计算两个日期之间的天数差。

首先检查两个日期的大小,并将较大的日期存储在 max 中,将较小的日期存储在 min 中。

然后,它使用一个循环来计算 min 到 max 之间的天数差。

最后,它返回天数差乘以一个标志位,该标志位表示两个日期之间的天数差是正数还是负数。

int Date::operator-(const Date& d)
{int flag = 1;Date max = *this;Date min = d;if (*this < d){int flag = -1;max = d;min = *this;}int n = 0;while (min != max){++min;++n;}return n * flag;
}

计算天数差值函数的测试:

int main()
{Date d1(2024, 2, 3);Date d2(2024, 2, 10);cout << (d2 - d1) << endl;}

距离新年还剩7天了,提前祝大家新年快乐!!!

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

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

相关文章

2.03作业

1.请编程实现单向循环链表的头插&#xff0c;头删&#xff0c;尾插&#xff0c;尾删。 2.请编程实现单向循环链表约瑟夫环 约瑟夫环&#xff1a;用循环链表编程实现约瑟夫问题 n个人围成一圈&#xff0c;&#xff0c;从某人开始报数&#xff0c;1,2&#xff0c;......,m,数到…

【算法与数据结构】718、1143、LeetCode最长重复子数组 最长公共子序列

文章目录 一、718、最长重复子数组二、1143、最长公共子序列三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、718、最长重复子数组 思路分析&#xff1a; 第一步&#xff0c;动态数组的含义。 d p [ i ] [ j ] dp[i]…

【Java程序设计】【C00191】基于SSM的线上鲜花商城管理系统(论文+PPT)

基于SSM的线上鲜花商城管理系统&#xff08;论文PPT&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于ssm的线上鲜花商城的管理系统 本系统分为前台用户和后台管理员2个功能模块。 前台用户&#xff1a; 当游客打开系统的网址后&#xff0c;首先看…

SpringAOP+SpringBoot事务管理

项目搭建SpringAOPSpringBoot中管理事务AOP案例实战-日志记录日志系统 一、项目搭建 第一步&#xff1a;构建项目 第二步&#xff1a;导入依赖 第三步&#xff1a;配置信息 自动配置&#xff08;项目自动生成的启动类&#xff09; /*** 启动类&#xff1a;申明当前类是一个…

unity3d的海盗王白银城演示

这是一个外网上的下载的海盗王unity3d制作的白银城演示场景。 地图只含有白银城区&#xff0c;没有野外和怪物。 当然也没有服务器端的。 我对灯光、摄像头、天空背景等做过调整&#xff0c;使它显示起来比较鲜丽。 它的模型和贴图是直接拿了海盗的&#xff0c;没有做过优化调整…

《PCI Express体系结构导读》随记 —— 第II篇 第4章 PCIe总线概述(5)

接前一篇文章&#xff1a;《PCI Express体系结构导读》随记 —— 第II篇 第4章 PCIe总线概述&#xff08;4&#xff09; 4.1.2 PCIe总线使用的信号 PCIe设备使用两种电源信号供电&#xff0c;分别是Vcc与Vaux&#xff0c;其额定电压为3.3V。其中Vcc为主电源&#xff0c;PCIe设备…

Leetcode的AC指南 —— 栈与队列 :1047.删除字符串中的所有相邻重复项

摘要&#xff1a; **Leetcode的AC指南 —— 栈与队列 &#xff1a;1047.删除字符串中的所有相邻重复项 **。题目介绍&#xff1a;给出由小写字母组成的字符串 S&#xff0c;重复项删除操作会选择两个相邻且相同的字母&#xff0c;并删除它们。 在 S 上反复执行重复项删除操作&a…

vue-3d-model

vue-3d-model - npm GitHub - hujiulong/vue-3d-model: &#x1f4f7; vue.js 3D model viewer component 通过该插件降低Threejs的使用难度 vue项目加载三维模型&#xff0c;我把模型放在了服务器的tomcat里面&#xff0c;需要对tomcat的fbx项目文件夹设置跨域&#xff0c;如…

【Linux笔记】文件描述符与重定向

一、Linux关于文件操作的一些系统调用 1、open和close 我们在C语言阶段已经学过很多文件操作的函数&#xff0c;今天我们要来看看操作系统中对于文件是怎么操作的。 1.1、open与close的用法 C语言的库函数中有很多关于文件操作的接口&#xff0c;包括fopen、fclose、fprint…

C#验证字符串是否纯字母:用正则表达式 vs 用Char.IsLetter方法加遍历

目录 一、使用的方法 1.使用正则表达式 2.使用Char.IsLetter方法 二、实例 1. 源码 2.生成效果 一、使用的方法 1.使用正则表达式 使用正则表达式可以验证用户输入的字符串是否为字母。匹配的正则表达式可以是&#xff1a;^[A-Za-z]$、^[A-Za-z]{1,}$、^[A-Za-z]*$。 …

x264 码率控制中自适应量化模式 AQ mode分析

AQ mode Adaptive Quantization mode&#xff0c;即自适应量化模式&#xff0c;根据 MB 的复杂度来调整每个 MB 量化时的量化参数。该模式可以更好地将码率分配到各个宏块中&#xff0c;以获得更好的视频质量和压缩效果。x264 中与之相关的参数i_aq_mode、f_aq_strength。 i_…

367. Valid Perfect Square(有效的完全平方数)

题目描述 给你一个正整数 num 。如果 num 是一个完全平方数&#xff0c;则返回 true &#xff0c;否则返回 false 。 完全平方数 是一个可以写成某个整数的平方的整数。换句话说&#xff0c;它可以写成某个整数和自身的乘积。 不能使用任何内置的库函数&#xff0c;如 sqrt(…