日期类代码实现-C++

一、目标

        通过前面对类和对象的介绍我们可以自己通过C++代码初步实现一个简单的日期类。

实现的主要操作有:

1.日期类的构造函数

2.日期类的拷贝构造函数(在头文件中实现)

3.日期类的比较运算符重载

4.日期类的计算运算符重载

5.流插入运算符重载。

二、总体思路

        首先,我这里采用的是分文件编程的方式来实现的日期类。

分别为:

1.头文件:Date.h

        该文件的主要目的是对上述目标所要实现的所有操作进行函数的声明。同时,还要包含在

源文件Date.cpp 中定义时所需要用到的头文件函数。

2.源文件:Date.cpp

        该文件的目的主要是用于对 头文件Date.h 所声明的所有函数进行定义,从而完成各个函数所要实现的操作。

3.源文件:Test.cpp

        该文件的目的主要是用于检测 源文件Date.cpp 中定义的函数是否能正常够使用并且达到所要实现的操作。

三、代码实现及具体思路

1.头文件:Date.h

        通过上面思路的介绍,我们可以知道,我们的目的是创建一个日期类,然后在日期类中自我声明:日期类的构造函数、日期类的比较运算符重载、日期类的计算运算符重载以及流插入运算符重载。并实现拷贝构造函数。

注意:通过我们前面对类和对象的介绍可知,因为在实现日期类过程中,我们没有动态申请空间,所以我们只需使用编译器默认生成的析构函数就可以,因此,我们不需要自己再定义一个析构函数)

代码如下:

#pragma once#include <iostream>
#include <assert.h>using namespace std;
class Date
{public:Date(int year = 1, int month = 1, int day = 1);void Print()const{cout << _year << '-' << _month << '-' << _day << endl;}Date(const Date& d){_year = d._year;_month = d._month;_day = d._day;}//日期类的比较运算符的重载bool operator<(const Date& x) const;bool operator==(const Date& x) const;bool operator<=(const Date& x) const;bool operator>(const Date& x) const;bool operator>=(const Date& x) const;bool operator!=(const Date& x) const;//日期类的计算运算符的重载int Get_MonthDay(int year,int month);		//获取该月份的天数Date& operator+=(int day);Date operator+(int day)const;Date& operator-=(int day);Date operator-(int day)const;Date& operator++();		//前置++Date operator++(int);		//后置++Date& operator--();			//前置--Date operator--(int);		//后置--int operator-(const Date& x) const;// 流插入不能写成成员函数?// 因为Date对象默认占用第一个参数,就是做了左操作数// 写出来就一定是下面这样子,不符合使用习惯//d1 << cout; // d1.operator<<(cout); //void operator<<(ostream& out);// 友元函数声明friend ostream& operator<<(ostream& out, const Date& d);friend istream& operator>>(istream& in, Date& d);
private:int _year;int _month;int _day;
};ostream& operator<<(ostream& out, const Date& x);
istream& operator>>(istream& in, Date& x);

2.源文件:Date.cpp

        对于实现下面函数,我们需要首先定义一个获取当前月份天数的函数

代码实现:

//因为平年闰年的2月天数不一样所以我们需定义一个获取月份的函数来解决这一问题
int Date::Get_MonthDay(int year, int month)		//获取该月份的天数
{static int daysArr[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;}else{return daysArr[month];}
}

1.日期类的构造函数

 思路:

        我们在通过日期类构造函数初始化所定义的日期时,我们需要判断我们所定义的日期是否合法,若不合法,则需要返回并提示

代码实现:

Date::Date(int year, int month, int day)
{//判断所初始化的日期是否合法if (month > 0 && month < 13&&day>=1&&day<= Get_MonthDay(year, month)){_year = year;_month = month;_day = day;}else{cout << "非法日期" << endl;assert(false);}
}

2.日期类的比较运算符重载

思路:

        对于比较类的运算符重载来说,因为比较运算符具有互斥性,所以我们只需定义出 < 运算符重载和 == 运算符重载,然后其他运算符复用上面所定定义的两个运算符即可。并且在比较的同时,我们不会改变参数的值,所以我们可以在函数尾部加const用于修饰内部的this指针,这样的话,const修饰的类型我们也可以通过比较运算符来比较。

代码实现:

bool Date::operator<(const Date& x) const
{if (_year < x._year){return true;}else if (_year == x._year && _month < x._month){return true;}else if (_year == x._year && _month == x._month && _day < x._day){return true;}else{return false;}
}bool Date::operator==(const Date& x) const
{if (_year == x._year && _month == x._month && _day == x._day){return true;}else{return false;}
}bool Date::operator<=(const Date& x) const
{//复用上面定义的重载运算符:< , ==return *this < x || *this == x;
}bool Date::operator>(const Date& x) const
{//复用上面定义的重载运算符:<=return !(*this <= x);
}bool Date::operator>=(const Date& x) const
{//复用上面定义的重载运算符:> , ==return *this > x || *this == x;
}bool Date::operator!=(const Date& x) const
{//复用上面定义的重载运算符:==return !(*this == x);
}

3.日期类的计算运算符重载

思路:

        对于日期类的计算运算符重载的定义,我们可以先定义 += 运算符重载和 -= 运算符重载,然后其他运算符重载的定义我们可以复用这两个运算符重载,从而实现各个运算符所要实现的目的。

代码实现:

Date& Date::operator+=(int day)
{if (day < 0){return *this -= (-day);}_day = _day + day;while (_day > Get_MonthDay(_year, _month)){_day = _day-Get_MonthDay(_year, _month);++_month;if (_month == 13){_month = 1;++_year;}}return *this;
}Date Date::operator+(int day)const
{if (day < 0){return *this - (-day);}//复用上面定义的重载运算符:+=Date tem(*this);tem+= day;return tem;
}Date& Date::operator-=(int day)
{if (day < 0){return *this += (-day);}_day = _day - day;while (_day < 1){--_month;if (_month <1 ){_month = 12;--_year;}_day = _day + Get_MonthDay(_year, _month);}return *this;
}Date Date::operator-(int day)const
{if (day < 0){return *this + (-day);}//复用上面定义的重载运算符:-=Date tem(*this);tem -= day;return tem;
}Date& Date::operator++()
{//复用上面定义的重载运算符:+=*this += 1;return *this;
}Date Date::operator++(int)
{//复用上面定义的重载运算符:+Date tem = *this;*this += 1;return tem;
}Date& Date::operator--()
{//复用上面定义的重载运算符:+=*this -= 1;return *this;
}Date Date::operator--(int)
{//复用上面定义的重载运算符:+Date tem = *this;*this -= 1;return tem;
}

        实现两个日期之间相减求天数时,我们可以先判断哪个日期大,从而确定出所求的天数是正数还是负数,即用flage的正负来实现。接着我们定义一个n来统计天数,然后我们通过while循环,++最小的日期,并且++天数直到最小日期和最大日期相等的时候结束,这时候我们返回n*flage的值即是所求天数。

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

4.流插入运算符重载。

思路:

        对于日期类使用系统中的流插入(只能插入内置类型)时并不能实现所期望的操作,因为日期类是自定义类型,所以我们就需要自己定义一个流插入来实现这个操作

	// 流插入不能写成成员函数?// 因为Date对象默认占用第一个参数,就是做了左操作数// 写出来就一定是下面这样子,不符合使用习惯//d1 << cout; // d1.operator<<(cout); //void operator<<(ostream& out);

因此,这里我们通过友元函数,在全局中定义流插入的运算符重载

代码实现:

ostream& operator<<(ostream& out, const Date& x)
{out << x._year << "年" << x._month << "月" << x._day << "日" << endl;return out;
}istream& operator>>(istream& in, Date& x)
{int year, month, day;in >> year >> month >> day;if (month > 0 && month < 13&& day > 0 && day <= x.Get_MonthDay(year, month)){x._year = year;x._month = month;x._day = day;}else{cout << "非法日期" << endl;assert(false);}return in;
}

3.源文件:Test.cpp

Test1:

用于检测日期类的比较运算符的重载

void Test1()		//用于检测日期类的比较运算符的重载
{Date s1(2005, 2, 16);Date s2(2024, 8, 12);cout << "bool operator<(const Date& x) const:" << (s1 < s2) << endl;cout << "bool operator==(const Date& x) const:" << (s1 == s2) << endl;cout << "bool operator<=(const Date& x) const:" << (s1 <= s2) << endl;cout << "bool operator>(const Date& x) const:" << (s1 > s2) << endl;cout << "bool operator>=(const Date& x) const:" << (s1 >= s2) << endl;cout << "bool operator!=(const Date& x) const:" << (s1 != s2) << endl;
}

Test2:

用于检测日期类的计算运算符的重载:+= , +

void Test2()		//用于检测日期类的计算运算符的重载:+= , +
{Date s1(2005, 2, 16);s1.Print();s1 += 10000;s1.Print();Date s2(2005, 2, 16);s2.Print();Date s3=s2+10000;s3.Print();
}

Test3:

用于检测日期类的计算运算符的重载:-= , -

void Test3()		//用于检测日期类的计算运算符的重载:-= , -
{Date s1(2005, 2, 16);s1.Print();s1 -= 1000;s1.Print();Date s2(2005, 2, 16);s2.Print();Date s3 = s2 - 1000;s3.Print();
}

Test4:

用于检测日期类的计算运算符的重载:--

void Test4()		//用于检测日期类的计算运算符的重载:--
{Date s2(2005, 2, 16);Date s3(2005, 2, 16);Date s4;s4=s2--;s4.Print();s4 = --s3;s4.Print();
}

Test5:

用于检测日期类的计算运算符的重载:++

void Test5()		//用于检测日期类的计算运算符的重载:++
{Date s2(2005, 2, 16);Date s3(2005, 2, 16);Date s4;s4 = s2++;s4.Print();s4 = ++s3;s4.Print();
}

Test6:

用于检测日期类之间的计算运算符的重载:-

void Test6()		//用于检测日期类之间的计算运算符的重载:-
{Date s1(2005, 2, 16);Date s2(2024, 8, 13);cout << "int operator-(const Date& x) const:" << (s1 - s2) << endl;
}

Test7:

用于检测日期类之间的计算运算符的重载:<< , >>

void Test7()		//用于检测日期类之间的计算运算符的重载:<< , >>
{Date s1;cin >> s1;cout << s1 << endl;cout << s1 + 100 << endl;
}

四、结语:

         上述内容,即是我个人对C++日期类的个人见解及代码实现。若有大佬发现哪里有问题可以私信或评论指教一下。非常感谢各位uu们的点赞,关注,收藏,还望各位多多关照,让我们一起进步吧!

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

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

相关文章

【Linux】 gdb-调试器初入门(简单版使用)

&#x1f525;系列文章&#xff1a;《Linux入门》 目录 一、背景 二、什么是GDB &#x1f337;定义 &#x1f337;GDB调试工具---提供的帮助 三、GDB的安装教程-Ubuntu &#x1f337;gdb的安装 四、哪类程序可被调试 &#x1f337;程序的发布方式 &#x1f337;Debug版…

Vscode——如何实现 Ctrl+鼠标左键 跳转函数内部的方法

一、对于Python代码 安装python插件即可实现 二、对于C/C代码 安装C/C插件即可实现

5.3 表结构设计与数据完整性

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;欢迎订阅相关专栏&#xff1a; 工&#x1f497;重&#x1f497;hao&#x1f497;&#xff1a;野老杂谈 ⭐️ 全网最全IT互联网公司面试宝典&#xff1a;收集整理全网各大IT互联网公司技术、项目、HR面试真题.…

Linux:开发工具(2)

一、Linux编译器-gcc/g使用 1.1 为什么我们可以用C/C做开发呢&#xff1f; 无论是在windows、还是Linux中&#xff0c;C的开发环境不仅仅指的是vs、gcc、g&#xff0c;更重要的是语言本身的头文件&#xff08;函数的声明&#xff09;和库文件&#xff08;函数的实现&#xff0…

Cesium 实战 - 自定义纹理材质系列之 - 半球雷达效果(力场闪烁)

Cesium 实战 - 自定义纹理材质系列之 - 半球雷达效果(力场闪烁) 核心代码完整代码在线示例Cesium 给实体对象(Entity)提供了很多实用的样式,基本满足普通项目需求; 但是作为 WebGL 引擎,肯定不够丰富,尤其是动态效果样式。 对于实体对象(Entity),可以通过自定义材…

后端Web之数据库(以MySQL为例)

目录 1.概述 2.MySQL 3.DDL 4.DML 5.DQL 1.概述 对于我们自己写的一些小功能&#xff0c;数据一般存储在文件中&#xff0c;比如XML文件。而在实际项目中&#xff0c;数据都是存放在数据库中的。数据库&#xff08;DataBase &#xff09;是一个存储数据的集合&#xff0c…

OpenCv图像处理: 时域滤波与频域滤波

时域滤波&#xff1a; 空间域滤波的步骤一般如下&#xff1a; 1. 选择滤波器 选择一种低通滤波器&#xff0c;常见的包括&#xff1a; 均值滤波&#xff08;平均滤波器&#xff09;高斯滤波&#xff08;Gaussian filter&#xff09; 2. 定义滤波器核 根据选择的滤波器类型&…

【C++篇】迈入新世界的大门——初识C++(上篇)

文章目录 C发展历史C起源C版本更新C23小故事 C在工作领域的应用C参考网站及文档书籍编程语言排行榜C难度参考文档书籍参考文档参考书籍 C第一个程序命名空间为什么要使用namespacenamespace定义及规则命名空间使用 C输入&输出名字含义 缺省参数函数重载 C发展历史 C起源 …

VUE中出现Cannot find module ‘@/api/xxx.js‘ or its corresponding type declarations

在使用VSCode编写Vue程序时发现之前使用以下代码时却报出了错误 import {getEmployeeList} from /api/employee\ 保证文件地址正确且其中的方法也可以正常调用&#xff0c;只是报出了错误&#xff0c;该行代码上加入一个‘//ts-ignore’就可以解决。 修改后的代码 //ts-ig…

python基础篇(15):闭包

在函数嵌套的前提下&#xff0c;内部函数使用了外部函数的变量&#xff0c;并且外部函数返回了内部函数&#xff0c;我们把这个使用外部函数变量的内部函数称为闭包。 1 简单闭包 def outer(logo):def inner(msg):print(f"<{logo}>{msg}<{logo}>")retu…

苹果(ios)私钥证书和profile文件申请教程

苹果&#xff08;ios&#xff09;私钥证书&#xff0c;可以理解为p12后缀的苹果证书&#xff0c;我们在苹果开发者中心可以生成cer格式的证书&#xff0c;然后使用mac电脑或者第三方转换成p12后缀格式的私钥证书。 证书profile文件&#xff0c;又叫描述文件&#xff0c;这个文…

Android系统和开发--安全性和权限管理 SELinux 策略 安全架构

学习android权限知识 SElinux chmod -R 777 ./ setenforce 0 adb root su fastboot oem at-unlock-vboot adb disable-verity Android权限 Android系统是基于Linux内核构建的&#xff0c;因此它继承了Linux的权限管理机制。Android应用需要通过声明权限来访问系统的某些功能&…

融资融券利率和手续费详情,融资融券开通门槛50W资产必须沪深市值?

融资融券利率和手续费 融资融券就是可以向证券公司借钱借券来进行证券交易&#xff0c;实现杠杆操作。融资是向证券公司借款买入股票&#xff0c;而融券则是向证券公司借入股票并卖出。 融资融券的利率是浮动的、个性化的&#xff0c;但一般最低可以达到4.0%~5.0%&#xff0c…

Selenium + Python 自动化测试14(发送报告)

我们的目标是&#xff1a;按照这一套资料学习下来&#xff0c;大家可以独立完成自动化测试的任务。 上一篇我们讨论了使用HTMLTestRunner 生成HTML报告的方法。 本篇文章我们接着讲生成HTML报告是否可以自动邮件发送出去&#xff0c;提高我们测试报告的及时性&#xff0c;方便…

WordPress美化节日灯笼插件,适合春节的时候使用

源码介绍&#xff1a; WordPress美化节日灯笼插件&#xff0c;适合每年过年的时候安在网站上使用&#xff0c;这款插件可以备用着&#xff0c;一款WordPress节日灯笼美化插件&#xff0c;可以给网页自动加一个灯笼效果使用说明&#xff1a;到网站WP后台 - 插件 - 安装插件 - 上…

Java代码基础算法练习-乘阶求和-2024.08.18

对应的源代码可以在我的 Gitee 仓库中找到&#xff0c;欢迎star~ [Gitee 仓库](https://gitee.com/yukongji/java-basic-algorithm) 任务描述&#xff1a; 求Sn1!2!3!4!5!…n!之值&#xff0c;其中n是一个数字(n<10)。 解决思路&#xff1a; 输入: 读取用户输入的 n 值。检查…

Android:使用Gson常见问题(包含解决将Long型转化为科学计数法的问题)

一、解决将Long型转化为科学计数法的问题 1.1 场景 将一个对象转为Map类型时&#xff0c;调用Gson.fromJson发现&#xff0c;原来对象中的long类型的personId字段&#xff0c;被解析成了科学计数法&#xff0c;导致请求接口失败&#xff0c;报参数错误。 解决结果图 1.2、Exa…

leetcode108.把升序数组转换成二叉搜索树

题目描述 [-10,-3,0,5,9] 转换成如下二叉搜索树&#xff1a; 解题的核心原理是&#xff1a;二叉搜索树的中序遍历结果是一个升序数组&#xff0c;所以根节点的数值&#xff0c;也位于数组的中部。 class Solution {public TreeNode sortedArrayToBST(int[] nums) {return h…

基于Hadoop的汽车大数据分析系统设计与实现【爬虫、数据预处理、MapReduce、echarts、Flask】

文章目录 有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主项目介绍爬虫数据概览HIve表设计Cars Database Tables1. cars_data2. annual_sales_volume3. brand_sales_volume4. city_sales_volume5. sales_volume_by_year_and_brand6. sales_distribu…

MATLAB 手动实现一种高度覆盖值提取建筑物点云的方法(74)

专栏往期文章,包含本章 MATLAB 手动实现一种高度覆盖值提取建筑物点云的方法(74) 一、算法介绍二、算法实现1.代码2.效果总结一、算法介绍 手动实现一种基于高度覆盖值的建筑物点云提取方法,适用于高大的城市建筑物,比只利用高度提取建筑物的方法更加稳定和具有价值,主要…