C++:日期类的实现

目录

一、前言

二、头文件

三、各个函数的实现

打印、检查日期及获取日期

=、+=、-=、-、+

==、<、<=、>、>=、 !=

日期-日期

>>、<<


一、前言

    前面几篇讲了关于类和对象的一些知识,本篇就来实现一下前面用到的日期类。

二、头文件

    先写上头文件,明确我们要实现哪些函数,还有一些实现函数需要用到的头文件,在头文件中定义日期类及其类中的函数。

#include<iostream>
using namespace std;
class date{friend ostream& operator<<(ostream& out, const date& d);friend istream& operator>>(istream& in, date& d);public:void Print();bool CheckDate();// 获取某年某月的天数int GetMonthDay(int year, int month);// 全缺省的构造函数date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}// 拷贝构造函数date(const date& d){_year = d._year;_month = d._month;_day = d._day;}// 赋值运算符重载date& operator=(const date& d);// 日期+=天数date& operator+=(int day);// 日期+天数date operator+(int day);// 日期-天数date operator-(int day);// 日期-=天数date& operator-=(int day);// 前置++date& operator++();// 后置++date operator++(int);// 后置--date operator--(int);// 前置--date& operator--();// >运算符重载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);// 日期-日期 返回天数int operator-(const date& d);private:int _year;int _month;int _day;};
ostream& operator<<(ostream& out, const date& d);
istream& operator>>(istream& in, date& d);

   这里写日期类的流输入和流输出用到的是友元函数的方法,如果是写在类里面的话,由于类函数自带的(Date* this),在使用时和我们的流输入流输出的习惯会相反,就像这样

b>>a>>cout

这样的写法就会很别扭,所以这里是用到了友元函数的写法来解决这样的问题。

三、各个函数的实现

打印、检查日期及获取日期

    打印就是按照 年/月/日 这种形式来打印,检查日期是用来判断输入的日期是否有误,获取日期后面函数的实现基本都需要用到获取日期的功能,这里作为一个函数实现会方便很多。

void date::Print()
{cout<<_year<< "/" << _month <<"/"<< _day << endl;
}
bool date::CheckDate()
{if (_month<1 || _month>13 || _day < 0||_day>GetMonthDay(_year,_month))return false;elsereturn true;
}
int date::GetMonthDay(int year, int month)
{static int monthday[13] = { -1,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;}elsereturn monthday[month];
}

    获取日期的函数这里再说一下,monthday数组给了13个元素是为了方便用的时候可以对应到我们的1到12月,第一个元素就随便写一个就行了,用来凑数的。

=、+=、-=、-、+

    这几个分别是日期的赋值、日期+=天数、日期+天数、日期-天数、日期-=天数

date& date::operator=(const date& d)
{_year = d._year;_month = d._month;_day = d._day;return *this;
}

    日期的赋值就是把单个的赋值改成年月日的赋值就行了。

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

    前面用到-=的代码是为了解决给的天数为负数的问题,直接转换成-=计算,后面+=的逻辑就是先让年月日中的日的值加上我们给的天数,在进入一个循环,不断地判断日的值是否大于月的最大天数,如果大于就让月数+1,继续循环判断,直到日的值小于该月的最大天数,期间如果月份大于了13就给年份+1,月份从1月重新开始加,最后就会得到加完天数后的月份了。

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

      -=也是类似的,前面避免给的天数为负值的情况,然后直接让日的值减去天数,进入循环,如果日的值为负数就要加上该月的最大天数,月份-1,直到日的值大于0,如过期间月份=0了就年份-1,月份从12月重新开始计算,最后得到日期。

date date::operator+(int day)
{date tem = *this;tem += day;return tem;
}
date date::operator-(int day)
{date tem = *this;tem -= day;return tem;
}

    有了前面的-=和+=,写-和+就可以直接套用了。

前置++、后置++、前置--、后置--

    在C++中为了区分++和--的前置和后置,后置的--和++是需要带参数的,这里需要注意一下。

date& date::operator++()
{*this += 1;return *this;
}
date date::operator++(int)
{date tem = *this;*this += 1;return tem;
}
date date::operator--(int)
{date tem = *this;*this -= 1;return tem;
}
date& date::operator--()
{*this -= 1;return *this;
}

    ++和--其实和前面的天数+-差不多,其实就是把给的day变成了1,这里也是直接套用前面的-=和+=,这里给的代码看一下,就不过多的解释了。

==、<、<=、>、>=、 !=

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

     判断两个日期是否相同比较一下年月日就行了,很简单。

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;
}

     比较两个日期的大小,先比较两个日期的年份,如果相等再比较月份,最后再比较天数就行了,也是比较简单的代码,这里写的<的,也就是左边的日期比右边的日期小就返回true,反之则是false,比较大小的逻辑,<和>是一样的。

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);
}bool date::operator != (const date& d)
{return !(*this == d);
}

      后面的函数实现就可以套用前面两个函数,小于或者等于就是<=,不<=就是大于,不小于就是>=,否定相等相等就是!=,一环套一环还是挺有意思的不用写那么多代码。

日期-日期

    这个函数和前面的-不一样,前面的是日期-天数得到日期,这个是日期-日期得到天数

int date::operator-(const date& d)
{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;
}

      这个就是先把左边的日期定为大日期,右边的定为小日期,让小日期不断地++,直到和大日期相同为止,用一个变量记录,就可以得到差值,如果是右边的天数大,用到了一个flag的变量,就会返回负值。

>>、<<

ostream& operator<<(ostream& out, const date& d)
{out << d._year << "/" << d._month << "/" << d._day<<endl;return out;
}

     日期类的输出就是直接把对象的年月日输出就行了,这里的out就是cout的引用,返回cout是为了和原本的cout一样能输出多个对象。

istream& operator>>(istream& in, date& d)
{cout << "请按年月日依次输入日期:" << endl;in >> d._year >> d._month >> d._day;if (!d.CheckDate()){cout << "非法日期,请重新输入" << endl;cout << "请按年月日依次输入日期:" << endl;in >> d._year >> d._month >> d._day;}return in;
}

     日期类的输入也差不多,就是这里加了一个判断输入的日期是否合法,用到了前面日期检查的函数。


    本篇关于日期类的实现就到这里了,实现完后不要忘记了测试一下,好了,希望这篇内容对各位有帮助,如果有错误欢迎指出。

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

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

相关文章

TryHackMe 第3天 | Pre Security (中)

该学习路径讲解了网络安全入门的必备技术知识&#xff0c;比如计算机网络、网络协议、Linux命令、Windows设置等内容。上一篇中简短介绍了计算机网络相关的知识&#xff0c;本篇博客将记录 网络协议 部分。 How the web works? DNS in detail DNS (Domain name system&…

Java面试篇-AOP专题(什么是AOP、AOP的几个核心概念、AOP的常用场景、使用AOP记录操作日志、Spring中的事务是如何实现的)

文章目录 1. 什么是AOP2. AOP的几个核心概念3. AOP的常用场景4. 使用AOP记录操作日志4.1 准备工作4.1.1 引入Maven依赖4.1.2 UserController.java4.1.3 User.java4.1.4 UserService.java 4.2 具体实现&#xff08;以根据id查询用户信息为例&#xff09;4.2.1 定义切面类&#x…

SkyWalking 环境搭建部署

架构简介 skywalking agent : 和业务系统绑定在一起,负责收集各种监控数据skywalking oapservice : 是负责处理监控数据的,比如接受skywalking agent的监控数据,并存储在数据库中;接受skywalking webapp的前端请求,从数据库查询数据,并返回数据给前端。Skywalking oapserv…

华为HarmonyOS地图服务 7- 在地图上绘制标记

场景介绍 本章节将向您介绍如何在地图的指定位置添加标记以标识位置、商家、建筑等。 点标记用来在地图上标记任何位置,例如用户位置、车辆位置、店铺位置等一切带有位置属性的事物。Map Kit提供的点标记功能(又称 Marker)封装了大量的触发事件,例如点击事件、长按事件、…

【RabbitMQ】消息分发、事务

消息分发 概念 RabbitMQ队列拥有多个消费者时&#xff0c;队列会把收到的消息分派给不同的消费者。每条消息只会发送给订阅该队列订阅列表里的一个消费者。这种方式非常适合扩展&#xff0c;如果现在负载加重&#xff0c;那么只需要创建更多的消费者来消费处理消息即可。 默…

linux网络编程5

24.9.21学习目录 一.TCP1.TCP流程2.TCP相关函数3.三次握手 一.TCP 1.TCP流程 服务器流程&#xff1a; 创建套接字socket&#xff08;&#xff09;将套接字与服务器网络信息结构体绑定bind&#xff08;&#xff09;将套接字设置为监听状态listen&#xff08;&#xff09;阻塞等…

进程间的通信4 共享内存

共享内存 1.共享内存简介 共享内存是将分配的物理空间直接映射到进程的用户虚拟地址空间中&#xff0c;减少数据在内核空间缓存共享内存是一种效率较高的进程间通讯的方式在 Linux 系统中通过 ipcs -m 查看所有的共享内存 共享内存模型图 2.共享内存的创建 1.函数头文件 #…

Java算法专栏

专栏导读 在当今这个技术日新月异的时代&#xff0c;Java算法作为软件开发的核心&#xff0c;对于提升程序性能和解决复杂问题至关重要。本“Java算法”专栏旨在帮助读者深入理解Java编程语言中的算法原理和应用&#xff0c;通过实战案例和深入分析&#xff0c;使读者能够掌握…

Java汽车销售管理

技术架构&#xff1a; springboot mybatis Mysql5.7 vue2 npm node 功能描述&#xff1a; 针对汽车销售提供客户信息、车辆信息、订单信息、销售人员管理、财务报表等功能&#xff0c;提供经理和销售两种角色进行管理 效果图&#xff1a;

Python基础学习(3)

目录 一&#xff0c;函数 1&#xff0c;函数的定义 2&#xff0c;函数的参数 1&#xff0c;默认值 2&#xff0c;传参 3&#xff0c;返回值 4&#xff0c;变量的作用域 5&#xff0c;函数的调用 二&#xff0c;常用数据结构 1&#xff0c;列表 列表的定义 列表的特性…

【Geoserver使用】REST API调用(工作空间部分)

文章目录 前言一、Geoserver REST API(GeoServer Workspace)二、GeoServer Workspace接口使用1.GET请求 /workspaces2.POST请求 /workspaces3.GET请求 /workspaces/{workspaceName}4.PUT /workspaces/{workspaceName}5.DELETE /workspaces/{workspaceName} 总结 前言 根据Geos…

C++ | Leetcode C++题解之第423题从英文中重建数字

题目&#xff1a; 题解&#xff1a; class Solution { public:string originalDigits(string s) {unordered_map<char, int> c;for (char ch: s) {c[ch];}vector<int> cnt(10);cnt[0] c[z];cnt[2] c[w];cnt[4] c[u];cnt[6] c[x];cnt[8] c[g];cnt[3] c[h] - …

YOLOv10 简介

YOLOv10&#xff0c;由清华大学的研究人员基于 Ultralytics Python 包构建&#xff0c;引入了一种全新的实时目标检测方法&#xff0c;该方法解决了以往 YOLO 版本中后处理和模型架构方面的不足。通过消除非极大值抑制&#xff08;NMS&#xff09;并优化各种模型组件&#xff0…

【解决】chrome 谷歌浏览器,鼠标点击任何区域都是 Input 输入框的状态,能看到输入的光标

chrome 谷歌浏览器&#xff0c;鼠标点击任何区域都是 Input 输入框的状态&#xff0c;能看到输入的光标 今天打开电脑的时候&#xff0c;网页中任何文本的地方&#xff0c;只要鼠标点击&#xff0c;就会出现一个输入的光标&#xff0c;无论在哪个站点哪个页面都是如此。 我知道…

十四、运算放大电路

运算放大电路 1、理想运算放大器的概念。运放的输入端虚拟短路、虚拟断路之间的区别; 2、反相输入方式的运放电路的主要用途&#xff0c;以及输入电压与输出电压信号的相位 3、同相输入方式下的增益表达式(输入阻抗、输出阻抗)

Redis-01 入门和十大数据类型

Redis支持两种持久化方式&#xff1a;RDB持久化和AOF持久化。 1.RDB持久化是将Redis的数据以快照的形式保存在磁盘上&#xff0c;可以手动触发或通过配置文件设置定时触发。RDB保存的是Redis在某个时间点上的数据快照&#xff0c;可以通过恢复RDB文件来恢复数据。 2.AOF持久化…

55. QTableWidget的基本使用

1. 说明 在软件界面开发中,基本上离不开数据的展示以供客户查看一些比较关注的信息,比如公司做一个员工个人信息管理系统,需要一个界面能够展示员工个人基本信息,实现这种效果可以采用多种形式,其中比较简单的一种是使用QT提供的QTableWidget控件,这个控件已经封装了一些…

LeetCode 面试经典150题 190.颠倒二进制位

复习知识&#xff1a;正数的原码、反码、补码相同&#xff0c;负数的反码在其原码的基础上, 符号位不变&#xff0c;其余各个位取反&#xff0c;负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后1 (即在反码的基础上1)。 题目&#xff1a;颠倒给定的 32 位无符号…

Springboot3 + MyBatis-Plus + MySql + Uniapp 商品加入购物车功能实现(最新教程附源码)

Springboot3 MyBatis-Plus MySql Uniapp 商品加入购物车功能实现&#xff08;针对上一篇sku&#xff09; 1、效果展示2、后端代码2.1 model2.2 mapper server serverImpl 参照上一篇自动生成2.3 controller 3、前端代码3.1 index.js3.2 shop-info.vue3.3 ShopBottomButton.v…

计算机毕业设计hadoop+spark+hive新能源汽车销售数据分析系统 二手车销量分析 新能源汽车推荐系统 可视化大屏 汽车爬虫 机器学习

《HadoopSparkHive新能源汽车销售数据分析系统》开题报告 一、选题背景与意义 1.1 选题背景 随着全球对环境保护意识的增强和能源结构的转型&#xff0c;新能源汽车市场迅速崛起。新能源汽车的销售数据不仅反映了市场趋势和消费者偏好&#xff0c;还为企业决策、政府监管和政…