简单实现日期计算器

devtools/2024/9/25 11:10:03/

目录:

  • Date.h实现函数声明
  • Date.c实现函数功能
    • 构造函数
    • 六个比较函数
    • 日期 + 天数
    • 日期 - 天数
    • 日期 - 日期
    • 操作符++
    • 操作符--
    • 获取每月的天数

🚘正片开始

Date.h头文件中实现函数声明

#pragma once
#include<iostream>
using namespace std;
class Date
{friend istream& operator>>(istream& in, Date& d);public://构造函数Date(size_t year = 1970, size_t month = 1, size_t day = 1);//打印数据void Print_Date();//日期的比较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);//日期减日期int operator-(Date& d);//前置++Date& operator++();//后置++Date operator++(int);//日期--//前置--Date& operator--();//后置--Date operator--(int);//每月多少天(因为此函数会经常使用所以定义在类中,为内敛函数)int Month_Day(size_t year, size_t month){static int DayArr[13] = { 0,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;}return DayArr[month];}private:size_t _year;size_t _month;size_t _day;
};
构造函数
此构造函数为全缺省
Date::Date(size_t year, size_t month, size_t day)
{_year = year;_month = month;_day = day;
}

注意:此处是头文件和源文件分开写的,所以函数声明只需在头文件声明即可

六个比较函数

在这七个比较函数中,只需要先写 <== 其他比较函数直接进行复用即可轻松解决。

  1. 重载小于函数
bool Date::operator<(Date d)
{if (_year < d._year){return true;}else if (_year == d._year){if (_month < d._month){return true;}else if(_month==d._month){return _day < d._day;}}return false;
}

这里的小于函数实现原理是:

如果 *this 年小就返回 true , *this 年等就判断月,如果 *this 月小就返回true, *this 月等就判断天数,如果 *this 的天数小则返回 true 否则其他情况一律返回false

  1. 重载 == 函数
bool Date::operator==(Date d)
{return (_year==d._year)&&(_month==d._month)&&(_day==d._day);
}

下面的比较函数直接可以复用上面的两个函数使其实现函数难度大大降低,是一种非常巧妙的写法

  1. 重载 <= 函数
bool Date::operator<=(Date d)
{return (*this)<d || (*this)==d;
}

实现 <= 无非就是 <== 的其中一种情况 只需用一个或运算符连接即可完成此函数

  1. 重载 > 函数
bool Date::operator>(Date d)
{return !((*this) <= d);
}

实现 > 无非就是 <= 的反面 所以只需要对 <= 函数取反即可完成此函数

  1. 重载 >= 函数
bool Date::operator>=(Date d)
{return !((*this) < d);
}

实现 >= 无非就是 < 的反面 所以只需要对 < 函数取反即可完成此函数

  1. 重载 != 函数
bool Date::operator!=(Date d)
{return !((*this)==d);
}

实现 != 无非就是 == 的反面 所以只需要对 == 函数取反即可完成此函数

日期 - 天数
  1. 日期+天数
Date Date::operator+(int day)
{Date tmp(*this);if (day < 0){tmp -= (-day);}else{tmp += day;}return tmp;
}

函数里面的if语句是为了避免day为负数的情况,如果为负数则变成了 d-天数 原本应该是 d+天数 的为了让他传负数也能实现,我们复用了 -= 函数重载

  1. 日期+=天数
Date& Date::operator+=(int day)
{//为了避免day为负数造成*this-=day,所以我们复用了-=函数重载让它依旧可以实现相应的功能if (day < 0){*this -=  (- day);return *this;}_day += day;while (_day > Month_Day(_year, _month)){_day -= Month_Day(_year, _month);_month++;if (_month == 13){_year++;_month = 1;}}}
日期 - 天数
  1. 日期 - 天数
Date Date::operator-(int day)
{Date tmp(*this);if (day < 0){tmp += (-day);}else{tmp -= day;}return tmp;
}

小知识点:因为tmp为临时变量出了函数会被销毁,通常我们函数返回值会避免拷贝的发生通常使用引用返回,但是在这个地方无法使用引用是因为tmp为临时变量

  1. 日期 -= 天数
void Date::operator-=(int day)
{if (day < 0){*this += (-day);return;}_day -= day;while (_day <= 0){_month--;if (_month == 0){_year--;_month = 12;}_day += Month_Day(_year, _month);}
}
日期 - 日期
//假设是*this-d;
int Date::operator-(Date& d)
{//先假设*this>dDate max = *this;Date min = d;int count = 0;int flag = 1;//如果不是*this>dif (*this < d){max = d;min = *this;flag = -1;}while (min < max){++min;++count;}return count*flag;
}
操作符 ++
  1. 前置 ++
Date& Date::operator++()
{*this += 1;return *this;
}
  1. 后置 ++
Date Date::operator++(int)
{Date tmp(*this);*this += 1;return tmp;
}

由于 前置++ 和 后置++ 在函数上无法区别,所以c++创始人规定后置++ 函数括号内必须带一个 int 类型来进行区分,其实也可以把 前置++ 函数 和 后置++ 函数 理解为是运算符重载

操作符 --
  1. 前置 --
Date& Date::operator--()
{*this -= 1;return *this;
}
  1. 后置 --
Date Date::operator--(int)
{Date tmp(*this);*this -= 1;return tmp;
}
获取每月的天数
int Month_Day(size_t year, size_t month)
{//每月的天数static int DayArr[13] = { 0,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;}return DayArr[month];
}

单独把这个函数拿出来是因为此函数比较特别,因为这函数会经常使用所以定义在类中,为内敛函数。

大家可能对内敛函数比较陌生在此我给大家讲解一下内敛的好处👇

在一个类中定义的函数会被默认为内敛函数,前提是此函数代码量不多,因为大家都知道函数被调用的时候会建立栈帧,会消耗一定的空间和时间,如果编译器识别这个函数为内敛函数,编译器会自动展开函数,不调用函数栈帧 ,从而降低了时间和空间的消耗

接下来我们来讲讲获取天数的函数中的一些小细节

数组用static修饰是为了不让数组多次创建造成效率的浪费,定义13个元素是为了月份对应上下标

总结:本章主要是对运算符重载的应用,写个日期类的项目加强我们对知识点的记忆,本章也涉及到了一些小细节,需要细细斟酌,才能领悟,加油铁子们!!!


🎉🎉🎉完结


http://www.ppmy.cn/devtools/23665.html

相关文章

【spark】spark使用sql读取elasticsearch es索引,使用keystore配置用户密码

参考文章 spark配置elasticsearch属性汇总(基于es7) es-offical-doc Spark多方案读取Es性能比较 Spark读写ES数据时遇到的问题总结 es 查询多个索引的文档 spark table中使用明文密码 set es.index.auto.createtrue drop table if exists default.test_es01; create table d…

模块三:二分——153.寻找旋转排序数组中的最小值

文章目录 题目描述算法原理解法一&#xff1a;暴力查找解法二&#xff1a;二分查找疑问 代码实现解法一&#xff1a;暴力查找解法二&#xff1a;CJava 题目描述 题目链接&#xff1a;153.寻找旋转排序数组中的最小值 根据题目的要求时间复杂度为O(log N)可知需要使用二分查找…

C语言仿写strlen函数以及编程常见的错误、以及,打印菱形、空瓶换水、水仙花数、反转字符串等小案例

文章目录 前言一、仿写strlen函数二、编程常见的错误1. 编译型错误(语法错误)2. 链接型错误(链接期间)3. 运行时错误(最难找) 三、小案例1. 打印菱形2. 两个空瓶换一瓶水的实现3. 打印 aaaaaaaaaaaaaaa......的和4. 打印0-100000"水仙花数"5. 反转字符串 总结 前言 …

任务调度xxljob的使用记录

1.基本使用 a.下载代码&#xff0c;地址&#xff1a;https://gitee.com/xuxueli0323/xxl-job.git b.执行sql&#xff0c;修改配置&#xff0c;启动任务调度中心的代码 启动代码后任务调度中心访问地址&#xff1a;http://localhost:8080/xxl-job-admin&#xff08;自己机器…

超赞!只需几步,打造高颜值的CSS表单!(附代码)

你好&#xff0c;我是云桃桃。 一个希望帮助更多朋友快速入门 WEB 前端的程序媛。 云桃桃-大专生&#xff0c;一枚程序媛&#xff0c;感谢关注。回复 “前端基础题”&#xff0c;可免费获得前端基础 100 题汇总&#xff0c;回复 “前端工具”&#xff0c;可获取 Web 开发工具…

Linux中core dump开启使用教程

Linux中core dump开启使用教程 一、 什么是coredump? 程序由于各种异常或者bug导致在运行过程中异常退出或者中止&#xff0c;会产生一个叫做core的文件。 core文件会包含了程序运行时的内存&#xff0c;寄存器状态&#xff0c;堆栈指针&#xff0c;内存管理信息还有各种函数…

2023最新!Git2.40.0于win10环境下的安装

2023最新&#xff01;Git2.40.0于win10环境下的安装 git官网地址&#xff1a;https://git-scm.com/download/win/ 导航 文章目录 2023最新&#xff01;Git2.40.0于win10环境下的安装导航一、下载Git二、安装Git三、检验 一、下载Git Git官网选择自己所需的版本下载 二、安装…

开发使用Git的实践操作

程序员在使用Git进行代码管理时&#xff0c;涉及到许多常用的Git命令和功能&#xff0c;以下是详细的解释和分析&#xff1a; 程序员常用的Git命令 git init - 初始化一个新的Git仓库。这是开始使用Git跟踪项目的第一步。git clone - 复制一个远程仓库到本地&#xff0c;这样…