C++函数重载完成日期类相关计算

在这里插入图片描述

本文内容如下:

  • 1.创建类以及函数的声明
  • 2.日期加减天数
    • 1.月份天数
    • 2.函数实现
  • 3.日期比较大小
  • 4.日期减日期
    • 1.日期的前置和后置加加
    • 2.日期减日期的实现
  • 5.内置类型的cout和cin
      • 本文代码如下:

要完成日期类的相关计算要创建自定义的类型,然后用函数重载来完成

1.创建类以及函数的声明

我们先来定义一个Date的类

class Date
{
public:Date(int year = 1900, int month = 1, int day = 1);void Print();
private:int _year;int _month;int _day;
};

完成类的创建和打印:

Date::Date(int year, int month, int day)
{_year = year;_month = month;_day = day;
}void Date::Print()
{cout << _year << "/" << _month << "/" << _day << endl;
}

2.日期加减天数

先来声明函数:

class Date
{
public://日期加减天数Date operator+(int day);Date operator+=(int day);Date operator-(int day);Date operator-=(int day);
private:int _year;int _month;int _day;
};

1.月份天数

我们要想知道进行计算日期的天数加减难点在于:
如何区分2月小月和大月,而二月又要区分平年和闰年
我们可以通过封装一个函数来解决这个问题:

	int GetMonthDay(int year, int month){assert(month > 0 && month < 13);static int GetMonthDayArray[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 GetMonthDayArray[month];}

这里运用了数组取值的方法来实现
为了不频繁的创建数组将GetMonthDayArray 定于为全局变量
2月的判断优先判断 month == 2 来提升效率

2.函数实现

这里要注意的是:+= 和 + 的区别在于:

	int a = 1;int b = 1;int c = a + 1;      //a不改变b += 1;             //b直接改变

那么实现的方法就是先将天数直接加上,如果 _day 超出当前月的天数就让其减去当前月的天数直到合理即可
代码实现如下:

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

写完这个那么 + 就很好实现了,直接调用即可:

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

同理 - 和 -=

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

3.日期比较大小

函数声明:

class Date
{
public:Date(int year = 1900, int month = 1, int day = 1);void Print();int GetMonthDay(int year, int month){assert(month > 0 && month < 13);static int GetMonthDayArray[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 GetMonthDayArray[month];}//日期加减天数Date operator+(int day);Date& operator+=(int day);Date operator-(int day);Date& operator-=(int day);//日期比较大小bool operator>(const Date& d1) const;bool operator==(const Date& d1) const;bool operator!=(const Date& d1) const;bool operator<(const Date& d1) const;bool operator>=(const Date& d1) const;bool operator<=(const Date& d1)const;
private:int _year;int _month;int _day;
};

比较就很简单了,先比年后月 日:

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

将这两个写好后,后续比较直接调用这两个就行

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

4.日期减日期

1.日期的前置和后置加加

C++中重载函数区别前置与后置的区别在于:
后置加加有int参数

class Date
{
public://日期的前置和后置加加Date& operator++();Date operator++(int);
private:int _year;int _month;int _day;
};

实现起来就直接调用 + 或 += 就行
区别就在于返回值,而且后置加加要多几次拷贝

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

2.日期减日期的实现

声明:

class Date
{
public://日期的前置和后置加加Date& operator++();Date operator++(int);//日期减日期计算天数int operator-(Date& d1);
private:int _year;int _month;int _day;
};

有了加加日期的实现就变简单了
运用判断和加加结合就可以直接算出相差的天数
虽然效率慢了点,但是过程相对简单:

int Date::operator-(Date& d1)
{//假设法找小的日期int flag = 1;if (*this > d1){Date tmp = *this;*this = d1;d1 = tmp;flag = -1;}int day = 0;while (*this != d1){++*this;day++;}return day * flag;
}

5.内置类型的cout和cin

因为如果再类里面因为*this 默认写前面而导致 cin和cout无法写在前面从而写成这样:

	d1 << cout;

为了解决这样的问题我们只能将函数写在外面:
声明:

istream& operator>>(istream& in, Date& d1);
ostream& operator<<(ostream& out, Date& d1);

由于要访问Date 的私有要在类里面用friend 函数:

class Date
{friend istream& operator>>(istream& in, Date& d1);friend ostream& operator<<(ostream& out, Date& d1);
public://....
private:int _year;int _month;int _day;
};

先完成日期的输入判断是否正确:

bool Date::CheckDate()
{if (_month < 1 || _month > 12|| _day < 1 || _day > GetMonthDay(_year, _month)){return false;}elsereturn true;
}

cin的实现:

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

cout的实现:

ostream& operator<<(ostream& out, Date& d1)
{out << d1._year << "年" << d1._month << "月" << d1._day << "日" << endl;return out;
}

这样就可以实现直接输入输出自定义类型了
后续进行测试就行,这里就不演示了

本文代码如下:

Date.h

#pragma once#include<iostream>
using namespace std;#include <assert.h>class Date
{friend istream& operator>>(istream& in, Date& d1);friend ostream& operator<<(ostream& out, Date& d1);
public:bool CheckDate();Date(int year = 1900, int month = 1, int day = 1);void Print();int GetMonthDay(int year, int month){assert(month > 0 && month < 13);static int GetMonthDayArray[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 GetMonthDayArray[month];}//日期加减天数Date operator+(int day);Date& operator+=(int day);Date operator-(int day);Date& operator-=(int day);//日期比较大小bool operator>(const Date& d1) const;bool operator==(const Date& d1) const;bool operator!=(const Date& d1) const;bool operator<(const Date& d1) const;bool operator>=(const Date& d1) const;bool operator<=(const Date& d1)const;//日期的前置和后置加加Date& operator++();Date operator++(int);//日期减日期计算天数int operator-(Date& d1);
private:int _year;int _month;int _day;
};//输入和输出
istream& operator>>(istream& in, Date& d1);
ostream& operator<<(ostream& out, Date& d1);

Date.cpp

#define _CRT_SECURE_NO_WARNINGS 1
#include "Date.h"Date::Date(int year, int month, int day)
{_year = year;_month = month;_day = day;
}void Date::Print()
{cout << _year << "/" << _month << "/" << _day << endl;
}Date& Date::operator+=(int day)
{_day += day;while (_day > GetMonthDay(_year, _month)){_month++;if (_month == 13){_year++;_month = 1;}_day -= GetMonthDay(_year, _month);}return *this;
}Date Date::operator+(int day)
{Date tmp = *this;tmp += day;return tmp;
}Date Date::operator-(int day)
{Date tmp = *this;tmp -= day;return tmp;
}Date& Date::operator-=(int day)
{_day -= day;while (_day < 1){_month--;if (_month < 1){_month = 12;_year--;}_day += GetMonthDay(_year, _month);}return *this;
}bool Date::operator>(const Date& d1)const
{if (_year > d1._year){return true;}else if (_year==d1._year){if (_month > d1._month){return true;}else if (_month == d1._month){return _day > d1._day;}}else{return false;}
}bool Date::operator==(const Date& d1) const
{return _year == d1._year&& _month == d1._month&& _day == d1._day;
}bool Date::operator<(const Date& d1)const
{return !(*this >= d1);
}bool Date::operator>=(const Date& d1)const
{return (*this > d1 || *this == d1);
}bool Date::operator<=(const Date& d1)const
{return (*this < d1 || *this == d1);
}bool Date::operator!=(const Date& d1)const
{return !(*this == d1);
}Date& Date::operator++()
{*this += 1;return *this;
}Date Date::operator++(int)
{Date tmp = *this;++tmp;return tmp;
}int Date::operator-(Date& d1)
{//假设法找小的日期int flag = 1;if (*this > d1){Date tmp = *this;*this = d1;d1 = tmp;flag = -1;}int day = 0;while (*this != d1){++*this;day++;}return day * flag;
}bool Date::CheckDate()
{if (_month < 1 || _month > 12|| _day < 1 || _day > GetMonthDay(_year, _month)){return false;}elsereturn true;
}istream& operator>>(istream& in, Date& d1)
{cout << "请依次输入年月日:->";in >> d1._year >> d1._month >> d1._day;if (!d1.CheckDate()){cout << "非法日期!!!请重新输入" << endl;}return in;
}ostream& operator<<(ostream& out, Date& d1)
{out << d1._year << "年" << d1._month << "月" << d1._day << "日" << endl;return out;
}

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

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

相关文章

获取IPV6地址的参考网站|nginx解析IPV6|linux服务器获取IPV6的方法

获取IPV6地址的参考网站 网址1 https://v6.ident.me/ 网址2 https://ifconfig.co/ 网址3 https://ifconfig.me/ IPV6检测站点推荐 网址1 http://ipv6-test.ch/ linux服务器获取IPV6的方法 以centos7为例 curl -6 ifconfig.mecurl -6 https://v6.ident.mecurl -6 https:…

python安装-升级

这里写自定义目录标题 欢迎使用Markdown编辑器 欢迎使用Markdown编辑器 运行python 或pycharm时报错 [notice] A new release of pip is available: 23.1.2 -> 24.2 [notice] To update, run: python.exe -m pip install --upgrade pipCMD 进入 DOS C:\Users\wang>pyt…

解密MQ消息积压:让你系统瞬间卡死的幕后黑手

文章目录 什么是MQ消息积压&#xff1f;消息积压的常见原因案例分析&#xff1a;如何处理消息积压&#xff1f;场景1&#xff1a;消费者处理速度过慢场景2&#xff1a;消息生产速度过快 如何预防消息积压&#xff1f;1. **监控与告警**2. **动态扩容**3. **限流与降级**4. **合…

插入与冒泡排序(C++)

\一、插入排序 1 简介 插入排序&#xff0c;也称为直接插入排序&#xff0c;其排序思想和我们平时打扑克牌时排序类似。 2 算法步骤 将第一个元素看作已排序序列&#xff0c;第二个到最后一个看作未排序序列。 第二个元素&#xff0c;与之前已排序号的序列进行对比&#x…

面试题---链表分割(安全性问题)

题目&#xff1a; 现有一链表的头指针 ListNode* pHead&#xff0c;给一定值x&#xff0c;编写一段代码将所有小于x的结点排在其余结点之前&#xff0c;且不能改变原来的数据顺序&#xff0c;返回重新排列后的链表的头指针。 假设有一链表&#xff1a; 给定x6 MySingleList …

乐(智)尚代驾-------Day3(afternoon关于aop特殊一栏)~

谢谢你们的阅读uu们&#xff01;~~ 下午这部分内容是aop往后啦&#xff0c;大家要明确一个思路&#xff0c;用aop进行简化操作更加方便 紧接上部分~ 登录校验 如何判断是否登录状态&#xff1f; – 判断请求头里面是否包含token字符串 – 根据token查询redis 如何实现&…

多源最短路径

文章目录 1. 01 矩阵&#xff08;542&#xff09;2. 飞地的数量&#xff08;1020&#xff09;3. 地图分析&#xff08;1162&#xff09;4. 地图中的最高点&#xff08;1765&#xff09; 1. 01 矩阵&#xff08;542&#xff09; 题目描述&#xff1a; 算法原理&#xff1a; 这…

骨传导耳机怎么选?健身教练测评五大畅销爆款骨传导耳机!

随着健康生活方式的普及&#xff0c;越来越多的人开始注重日常锻炼与健康管理。而在这股健身热潮中&#xff0c;骨传导耳机因其独特的佩戴方式和开放耳道的设计&#xff0c;成为了运动爱好者的新宠。它们不仅能够在运动时提供安全舒适的听觉体验&#xff0c;还能让使用者随时留…

Java入门:09.Java中三大特性(封装、继承、多态)03

5 多态 首先&#xff0c;什么是多态呢&#xff1f; 多态即事物的多种表现形态。 就像生活中&#xff0c;人就有多种表现形态&#xff1a;学生&#xff0c;老师&#xff0c;警察&#xff0c;医生等。 那么在Java中也有类似的概念 它的作用就是&#xff1a;在封装时&#xf…

【Deloitte】AI大模型时代C端应用生态变局

类比PC时代到移动互联网时代的发展&#xff0c;可以窥见AI时代的来临将带来诸多颠覆与创新&#xff0c;这让所有关注AI发展的人们既心生期待又满怀敬畏。 德勤中国《AI大模型时代C端应用生态变局》报告深入探讨了AI对C端应用影响的四大发展趋势。 趋势一&#xff1a;AI 大模型…

【zookeeper安装】zookeeper安装详细教程(单机/集群部署)(linux版)

文章目录 前言一、zookeeper简介二、获取Zookeeper安装包2.1. 离线获取2.2. 在线获取2.3. 解压包 三、单机部署3.1. 配置conf文件3.2. 启动服务 四、集群部署4.1. 概念4.2. 配置conf文件4.3. 创建myid文件4.3. 启动每个节点的zookeeper服务 五、配置systemctl管理&#xff08;选…

修改 Visual Studio 的主题颜色、背景颜色、字体

本人使用的是 VS2019 版本的。 点击上方工具栏中的【工具】-> 【选项】。 在 【环境】->【常规】中&#xff0c;可以更改整个界面的主题颜色。 浅色和深色的主题如下&#xff1a; 在【环境】->【字体和颜色】中&#xff0c;可以更改代码区的背景色。 不同背景示例&…

RK3568笔记六十:V4L2命令测试

若该文为原创文章,转载请注明原文出处。 测试V4L2是想移植韦老师的相机程序,但他使用的是V4L2方式采集摄像头。 而正点原子的rknn使用的是opencv。 这里记录测试过程 一、常用调试命令 1、抓取图像 使用 v4l2-ctl 抓取一帧图像:v4l2-ctl -d /dev/video0 --set-fmt-video…

计算机图形学 中心画圆算法 原理及matlab代码实现

中心画圆算法原理 总体思路&#xff1a; 将圆划分为八部分&#xff0c;先通过diF(xi1,yi-0.5)和隐函数Fx2y2-R2绘制八分之一的圆&#xff0c;然后通过圆的对称性确定另外七个部分的相应坐标绘制完整的圆。 求中点误差项递推公式&#xff1a; 从(x0,y0r)开始&#xff0c;因绘…

嵌入式流媒体SRT协议:send buffer和窗口延迟机制

Handshake Packets&#xff1a; 握手控制包&#xff08;“包类型”位 1&#xff09;用于在点对点的 SRT 会话中建立两个对等体之间的连接。早期版本的 SRT 依赖于握手扩展来在连接建立后立即交换某些参数&#xff0c;但自 1.3 版本起&#xff0c;集成机制确保所有参数作为握手…

Python使用YOLOv5图像识别教程包成功-以识别桥墩缺陷详细步骤分享

前置环境资源下载 提示&#xff1a;要开外网才能下载的环境我都放在了网盘里&#xff0c;教程中用到的环境可从这里一并下载&#xff1a; https://pan.quark.cn/s/f0c36aa1ef60 1. 下载YOLOv5源码 官方地址&#xff1a;GitHub - ultralytics/yolov5: YOLOv5 &#x1f680; …

9。maven必备小技巧

&#xff08;1&#xff09;配置Maven加速时&#xff0c;除了settings之外&#xff0c;还可如下图所示&#xff0c;配置如下&#xff1a; 若想实现Maven加速&#xff0c;最重要的即User settings file。&#xff08;先修改settings.xml&#xff09; &#xff08;2&#xff09;当…

哪个牌子的头戴式耳机性价比高?四大爆款性价比品牌推荐!

随着科技的不断进步和发展&#xff0c;头戴式耳机已经成为音乐爱好者和专业人士不可或缺的设备。进入2024年&#xff0c;市场上涌现出了一批性能卓越、音质优秀的新产品。这些新品不仅在音质上有了显著的提升&#xff0c;还在设计、舒适度和功能性上进行了全面的优化&#xff0…

(科普篇)公司防止泄密,应该做到哪些?教你10个方法有效阻止泄密事件发生!

公司防止泄密&#xff0c;应该做到哪些&#xff1f; 世事如棋局局新&#xff0c;信息之海波涛汹涌&#xff01; 甲曰&#xff1a;"企业之基&#xff0c;在于保密。泄密之祸&#xff0c;猛于虎也&#xff0c;如何防患于未然。吾友&#xff0c;可有良策&#xff1f;" …

lettuce引起的Redis command timeout异常

项目使用Lettuce&#xff0c;在自己的环境下跑是没有问题的。在给客户做售前压测时&#xff0c;因为客户端环境比较恶劣&#xff0c;service服务和中间件服务不在同一机房。服务启动后不一会就会出现Redis command timeout异常。 经过差不多两周的追查&#xff0c;最后没办法把…