【C++手撕系列】——设计日期类实现日期计算器

【C++手撕系列】——设计日期类实现日期计算器😎

  • 前言🙌
    • C嘎嘎类中六大护法实现代码:
      • 获取每一个月天数的函数源码分享
      • 构造函数源码分享
      • 拷贝构造函数源码分享
      • 析构函数源码分享
      • 赋值运算符重载函数源码分享
      • 取地址和const取地址运算符重载函数源码分享
      • 各种比较(> , >= ,< , <= , == , !=)运算符重载函数源码分享
      • 各种运算的 运算符重载函数源码分享
      • 流插入(cout)和流提取(cin)运算符重载函数源码分享
      • 日期 - 日期 函数源码分享
    • Date 日期类头文件源码:
    • Date 日期类功能文件源码:
    • Date 日期类测试文件源码:
    • 测试截图证明:
      • TestDate1函数的测试结果
      • TestDate2函数的测试结果![在这里插入图片描述](https://img-blog.csdnimg.cn/f38c9207a79a4ef98f9eb94b84c7e049.png)
      • TestDate3函数的测试结果
      • TestDate4函数的测试结果
    • 小结语:
  • 总结撒花💞

追梦之旅,你我同行

   
😎博客昵称:博客小梦
😊最喜欢的座右铭:全神贯注的上吧!!!
😊作者简介:一名热爱C/C++,算法等技术、喜爱运动、热爱K歌、敢于追梦的小博主!

😘博主小留言:哈喽!😄各位CSDN的uu们,我是你的博客好友小梦,希望我的文章可以给您带来一定的帮助,话不多说,文章推上!欢迎大家在评论区唠嗑指正,觉得好的话别忘了一键三连哦!😘
在这里插入图片描述

前言🙌

    哈喽各位友友们😊,我今天又学到了很多有趣的知识现在迫不及待的想和大家分享一下! 都是精华内容,可不要错过哟!!!😍😍😍

    最近学习了C++的类和对象这部分的内容,然后自己手痒痒,就在空闲的时候手撕了一个日期类,按照网页版日期计算器有的功能进行一个一一的实现。纯粹分享,如果大家对日期计算器感兴趣的话也可以去实现一个自己的日期计算器,也可以借鉴我写的代码,有不懂的也可以来问我哦~废话不多说,咋们开始啦!!!

C嘎嘎类中六大护法实现代码:

在C嘎嘎中,有六大护法一直守护我们的类。分别是:

  • 构造函数
  • 析构函数
  • 拷贝构造函数
  • 赋值运算符重载函数
  • 取地址重载函数
  • const取地址重载函数

获取每一个月天数的函数源码分享

这里要注意的就是闰年和平年的2月天数的确定。闰年2月是29,平年是28天。

//获取每一个月的天数
int Date::GetMonthDay(int year, int month) const
{int DateArray[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 DateArray[month];
}

构造函数源码分享

这里需要注意的就是输入非法日期的情况,所以这里要给个检查,当输入非法日期就报错!!!

//构造函数
Date:: Date(int year, int month , int day):_year(year),_month(month),_day(day)
{if (month < 1 || month > 12 || day < 1|| day > GetMonthDay(_year, _month)){cout << "输入日期非法" << endl;}
}

拷贝构造函数源码分享

这里可以不用写拷贝构造,编译器可以默认生成。

//拷贝构造函数
Date:: Date(const Date& d):_year(d._year), _month(d._month), _day(d._day)
{}

析构函数源码分享

这里可以不用写析构,编译器可以默认生成。

//析构函数
Date:: ~Date()
{}

赋值运算符重载函数源码分享

这里要避免 d1 = d1(自己给自己赋值)情况,所以加一个检查。其实也不用自己显示实现,编译器默认生成的赋值重载函数就可以了满足需求了~

//赋值运算符重载
Date& Date::operator=(const Date& d)
{if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;
}

取地址和const取地址运算符重载函数源码分享

一般这两个函数不用写,编译器默认生成的就可以了。这里知识闲着无聊先出来看看而已。

//取地址和const取地址运算符重载
Date* Date:: operator&()
{return this;
}const Date* Date:: operator&()const
{return this;
}

各种比较(> , >= ,< , <= , == , !=)运算符重载函数源码分享


//d1 < d2
bool Date::operator<(const Date& d) const
{if (_year < d._year){return true;}else if (_year == d._year && _month < d._month){return true;}else if (_year == d._year && _month == d._month && _day < d._day){return true;}else{return false;}
}//d1 == d2
bool Date::operator==(const Date& d) const
{if (_year == d._year && _month == d._month&& _day == d._day){return true;}return false;
}//d1 <= d2
bool Date::operator<=(const Date& d) const
{return (*this < d) || (*this == d);
}//d1 > d2
bool Date::operator>(const Date& d) const
{return !((*this) <= d);
}//d1 >= d2
bool Date::operator>=(const Date& d) const
{return !((*this) < d);
}//d1 != d2
bool Date::operator!=(const Date& d) const
{return !((*this) == d);
}

各种运算的 运算符重载函数源码分享

这里写好了+= ,然后复用 += 实现 + ;同理,写好了 -= ,我们就可以复用 -= 来实现 - 。前置++和后置++,区别是后置++参数列表加一个int进行占位,用于区分前置和后置++;同理前置- -与后置- -也是这样规定实现的。

// d1 += d2
Date& Date::operator+=(int day)
{if (day < 0){return (*this) -= -(day);}_day += day;//天满了进月while (_day > GetMonthDay(_year, _month)){_day -= GetMonthDay(_year, _month);++_month;//月满了进年if (_month == 13){++_year;_month = 1;}}return *this;
}Date Date::operator+(int day) const
{Date tem(*this);tem += day;return tem;
}Date& Date::operator-=(int day)
{if (day < 0){return (*this) += -(day);}_day -= day;while (_day <= 0){--_month;if (_month == 0){--_year;_month = 12;}_day += GetMonthDay(_year, _month);}return *this;
}Date Date::operator-(int day) const
{Date tem(*this);tem -= day;return tem;
}Date& Date::operator++()
{*this += 1;return *this;
}Date Date::operator++(int)
{Date tem(*this);++(*this);return tem;
}
Date& Date::operator--()
{(*this) -= 1;return *this;
}
Date Date::operator--(int)
{Date tem(*this);(*this) -= 1;return tem;
}

流插入(cout)和流提取(cin)运算符重载函数源码分享


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

日期 - 日期 函数源码分享

这个函数实现比较难想出来。这里先是确定出两个日期的大小关系,然后让小的日期不断++,n记录加的次数(也就是两个日期相隔的天数,当两个日期相等时,n*flag 就是结果。这里的flag是一个关键,当一开始是小日期 - 大日期时,flag 就是-1,计算出的答案自然是负数;当是大日期减小日期,flag就是1,答案自然就是正数。

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

Date 日期类头文件源码:

#pragma once#include<iostream>
using namespace std;class Date
{// 友元声明friend ostream& operator<<(ostream& out, const Date& d);friend istream& operator>>(istream& in, Date& d);public:int GetMonthDay(int year, int month) const;Date(int year = 1, int month = 1, int day = 1);//void Print() const;Date(const Date& d);~Date();// 只读函数可以加const,内部不涉及修改成员的都是只读函数bool operator<(const Date& d) const;bool operator==(const Date& d) const;bool operator<=(const Date& d) const;bool operator>(const Date& d) const;bool operator>=(const Date& d) const;bool operator!=(const Date& d) const;Date& operator+=(int day);Date operator+(int day) const;Date& operator-=(int day);Date operator-(int day) const;// 函数重载// 运算符重载// ++d1 -> d1.operator++()Date& operator++();// d1++ -> d1.operator++(0)// 加一个int参数,进行占位,跟前置++构成函数重载进行区分// 本质后置++调用,编译器进行特殊处理Date operator++(int);Date& operator--();Date operator--(int);Date& operator=(const Date& d);int operator-(const Date& d) const;// 日常自动生成的就可以// 不想被取到有效地址Date* operator&();const Date* operator&() const;
private:int _year;int _month;int _day;
};ostream& operator<<(ostream& out, const Date& d);
istream& operator>>(istream& in, Date& d);

Date 日期类功能文件源码:

#define _CRT_SECURE_NO_WARNINGS 1
#include"Date.h"//获取每一个月的天数
int Date::GetMonthDay(int year, int month) const
{int DateArray[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 DateArray[month];
}//构造函数
Date:: Date(int year, int month , int day):_year(year),_month(month),_day(day)
{if (month < 1 || month > 12 || day < 1|| day > GetMonthDay(_year, _month)){cout << "输入日期非法" << endl;}
}//拷贝构造函数
Date:: Date(const Date& d):_year(d._year), _month(d._month), _day(d._day)
{}//析构函数
Date:: ~Date()
{}//赋值运算符重载
//避免 d1 = d1(自己给自己赋值)情况
Date& Date::operator=(const Date& d)
{if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;
}//取地址和const取地址运算符重载
Date* Date:: operator&()
{return this;
}const Date* Date:: operator&()const
{return this;
}//d1 < d2
bool Date::operator<(const Date& d) const
{if (_year < d._year){return true;}else if (_year == d._year && _month < d._month){return true;}else if (_year == d._year && _month == d._month && _day < d._day){return true;}else{return false;}
}//d1 == d2
bool Date::operator==(const Date& d) const
{if (_year == d._year && _month == d._month&& _day == d._day){return true;}return false;
}//d1 <= d2
bool Date::operator<=(const Date& d) const
{return (*this < d) || (*this == d);
}//d1 > d2
bool Date::operator>(const Date& d) const
{return !((*this) <= d);
}//d1 >= d2
bool Date::operator>=(const Date& d) const
{return !((*this) < d);
}//d1 == d2
bool Date::operator!=(const Date& d) const
{return !((*this) == d);
}// d1 += d2
Date& Date::operator+=(int day)
{if (day < 0){return (*this) -= -(day);}_day += day;//天满了进月while (_day > GetMonthDay(_year, _month)){_day -= GetMonthDay(_year, _month);++_month;//月满了进年if (_month == 13){++_year;_month = 1;}}return *this;
}Date Date::operator+(int day) const
{Date tem(*this);tem += day;return tem;
}Date& Date::operator-=(int day)
{if (day < 0){return (*this) += -(day);}_day -= day;while (_day <= 0){--_month;if (_month == 0){--_year;_month = 12;}_day += GetMonthDay(_year, _month);}return *this;
}Date Date::operator-(int day) const
{Date tem(*this);tem -= day;return tem;
}ostream& operator<< (ostream& out,const Date& d)
{out << d._year << "/" << d._month << "/" << d._day << endl;return out;
}istream& operator>>(istream& in, Date& d)
{in >> d._year;in >> d._month;in >> d._day;return in;
}Date& Date::operator++()
{*this += 1;return *this;
}Date Date::operator++(int)
{Date tem(*this);++(*this);return tem;
}
Date& Date::operator--()
{(*this) -= 1;return *this;
}
Date Date::operator--(int)
{Date tem(*this);(*this) -= 1;return tem;
}int Date::operator-(const Date& d) const
{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;
}

Date 日期类测试文件源码:

#define _CRT_SECURE_NO_WARNINGS 
#include"Date.h"//6大默认成员函数测试
void TestDate1()
{//构造测试Date d1;//拷贝构造测试Date d2(2023, 8, 11);//流插入运算符重载测试cout << d1;cout << d2;//流提取运算符重载测试cin >> d1;cout << d1;//取地址运算符重载测试cout << &d1 << endl;cout << &d2;}//测试日期大小比较以及计算日期往后或者往前几天的日期是多少
void TestDate2()
{Date d1(2003, 8, 23);Date d2(2023, 8, 11);/*cout << (d1 < d2) << endl;cout << (d1 <= d2) << endl;cout << (d1 > d2) << endl;cout << (d1 >= d2) << endl;cout << (d1 == d2) << endl;cout << (d1 != d2) << endl;*///cout << d1;//d1 += 10000;//cout << d1;//d2 = d1 + 10000;//cout << d1;//cout << d2;//d1 += -1000;//cout << d1;//d1 = d2 + -1000;//cout << d1;/*d1 -= 11000;d2 = d1 - 1000;cout << d1;cout << d2;*/}void TestDate3()
{Date d1(2003, 8, 23);Date d2(2023, 8, 11);/*cout << d1;++d1;cout << d1;*//*cout << d1;d2 = d1++;cout << d1;cout << d2;*//*cout << d1;d2 = d1--;cout << d1;cout << d2;*//*cout << d1;d2 = ++d1;cout << d1;cout << d2;*//*cout << d1;d2 = --d1;cout << d1;cout << d2;*/
}void TestDate4()
{Date d1(2003, 8, 23);Date d2(2023, 8, 11);cout << (d2 - d1) << endl;cout << (d1 - d2) << endl;
}int main()
{//TestDate1();//TestDate2();//TestDate3();TestDate4();return 0;
}

测试截图证明:

TestDate1函数的测试结果

在这里插入图片描述

TestDate2函数的测试结果在这里插入图片描述

TestDate3函数的测试结果

在这里插入图片描述

TestDate4函数的测试结果

在这里插入图片描述
与网页版日期计算器测试结果一致!!!!!
在这里插入图片描述

小结语:

上述测试案例我只写了比较常规的,并没有做会更加仔细的测试。大家也可以帮我用链接: 网页版日期计算器测试一下我的程序有没有bug,我好及时更正!!!

总结撒花💞

   本篇文章旨在分享的是用C++ 设计日期类实现日期计算器的知识。希望大家通过阅读此文有所收获
   😘如果我写的有什么不好之处,请在文章下方给出你宝贵的意见😊。如果觉得我写的好的话请点个赞赞和关注哦~😘😘😘

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

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

相关文章

Jenkins持续集成-快速上手

Jenkins持续集成-快速上手 注&#xff1a;Jenkins一般不单独使用&#xff0c;而是需要依赖代码仓库&#xff0c;构建工具等。 搭配组合&#xff1a;GitGitee&#xff08;GitHub、GitLab&#xff09;MavenJenkins 前置准备 常见安装方式&#xff1a; war包Docker容器实例&…

sxs卡丢失数据如何找回?sxs卡数据丢失原因和修复办法分享!

说起sxs卡&#xff0c;你们是否有所了解呢&#xff1f;sxs卡具有很好的传输性能&#xff0c;能够存储照片和视频数据&#xff0c;主要被放置在索尼XDCAM EX型摄像机上。 而在使用sxs卡设备过程中&#xff0c;难免和其他设备一样&#xff0c;容易出现数据丢失情况。而如果丢失的…

【Spring】-Spring的IoC和DI

作者&#xff1a;学Java的冬瓜 博客主页&#xff1a;☀冬瓜的主页&#x1f319; 专栏&#xff1a;【Framework】 主要内容&#xff1a;什么是spring&#xff1f;IoC容器是什么&#xff1f;如何使代码解耦合&#xff1f;IoC的核心原理&#xff0c;IoC的优点。依赖注入/对象装配/…

R语言安装包Seurat

环境Ubuntu22&#xff0c;R4.1 also installing the dependencies ‘curl’, ‘openssl’, ‘httr’, ‘plotly’ R包安装的时候报了这个错误ERROR: dependencies httr, plotly are not available for package Seurat 解决方法&#xff0c;退出R&#xff0c;在terminal中键入…

突破笔试:力扣129. 求根节点到叶节点数字之和

1. 题目链接&#xff1a;129. 求根节点到叶节点数字之和 给你一个二叉树的根节点 root &#xff0c;树中每个节点都存放有一个 0 到 9 之间的数字。每条从根节点到叶节点的路径都代表一个数字&#xff1a;例如&#xff0c;从根节点到叶节点的路径 1 -> 2 -> 3 表示数字 …

QT中的PRO文件怎么进行相关的信息的注释?

小白学开发之QT下的PRO文件怎么进行注释&#xff0c;以及Pro文件的作用 Hello大家好&#xff0c;这里是程序员小白学开发&#xff0c;我是一个刚入门QT的初学者&#xff0c;晕乎晕乎的&#xff01;希望能够随时随地将自己所学的知识分享给大家&#xff0c;带着大学从零基础开始…

MySQL数据库-基础篇

基础篇 一、SQL 分类 DDL-数据库操作 查询 创建表 数据类型 数值类型 字符串类型 日期类型 添加 修改 删除字段 修改表名 删除表 小结 DML-数据增删改 添加数据 修改数据 删除数据 小结 DQL-数据查询数据 基本查询 条件查询 聚合函数 分组查询 排序查询 分页查…

现在国家正规相亲平台有哪些?盘点五款安全值得使用的相亲软件

随着互联网的普及&#xff0c;越来越多的人选择通过相亲软件寻找自己的另一半。但是&#xff0c;在众多相亲软件中靠谱的相亲软件有哪些呢&#xff0c;该如何选择&#xff1f;本文将盘点几款安全靠谱的相亲软件&#xff0c;可以了解看看哪个适合你。 第一款&#xff1a;一伴婚…

红帽停止公开Linux操作系统(RHEL)源代码,甲骨文等企业成立协会

根据报道&#xff0c;红帽&#xff08;Red Hat&#xff09;在8月11日宣布停止公开企业级Linux操作系统&#xff08;RHEL&#xff09;的源代码后&#xff0c;甲骨文、SUSE和CIQ昨日联合发布了一份声明。声明宣布成立了Open Enterprise Linux Association&#xff08;OpenELA&…

评述6种室内定位技术的底层原理及未来展望

从古至今&#xff0c;人类始终关心一个颇具哲学意味的问题——“我在哪里”。从千年前的人类在夜空下遥望星河&#xff0c;到依靠经验和模糊的观测绘制的初具现代化意味的地图&#xff0c;再到近现代人类在计算机技术、无线通信技术甚至空间技术的帮助下&#xff0c;不断探索更…

JVM入门到精通

一、JVM概念 1.1、什么是JVM Java Virtual Machine&#xff1a;Java虚拟机&#xff0c;用来保证Java语言跨平台 Java虚拟机可以看做是一台抽象的计算机&#xff0c;如同真实的计算机那样&#xff0c;它有自己的指令集以及各种运行时内存区域 Java虚拟机与Java语言并没有必然…

【办公自动化】使用Python一键提取PDF中的表格到Excel

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…