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.xdnf.cn/news/1538133.html

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

相关文章

Linux文件IO-基础知识了解及文件描述符

1、简介 本章给大家介绍 Linux 应用编程中最基础的知识&#xff0c;即文件 I/O&#xff08;Input、Outout&#xff09;&#xff0c;文件 I/O 指的是对文件的输入/输出操作&#xff0c;说白了就是对文件的读写操作&#xff1b;Linux 下一切皆文件&#xff0c;文件作为 Linux 系…

付费流量如何有效撬动自然流?

付费流量能够有效撬动自然流量的情况主要有三种。 首先&#xff0c;当直播刚开始时&#xff0c;流量通常较为泛化&#xff0c;转化效果不理想。在这种情况下&#xff0c;借助付费流量圈选精准受众&#xff0c;可以显著提高转化率。一旦形成转化&#xff0c;系统会根据这些转化行…

怎么使用Chrome与C++实现高效自动化测试

在软件开发过程中&#xff0c;自动化测试是确保代码质量和稳定性的关键步骤。谷歌浏览器&#xff08;Chrome&#xff09;提供了强大的开发者工具和丰富的API&#xff0c;结合C的强大功能&#xff0c;可以实现高效的自动化测试。本文将介绍如何使用Chrome和C来实现这一目标。&am…

vue2使用npm引入依赖(例如axios),报错Module parse failed: Unexpected token解决方案

报错情况 Module parse failed: Unexpected token (5:2) You may need an appropriate loader to handle this file type. 原因 因为我们npm install时默认都是下载最新版本&#xff0c;然后个别依赖的版本太新&#xff0c;vue2他受不起这个福分。 解决方法 先去package.js…

Rasa对话模型——做一个语言助手

1、Rasa模型 1.1 模型介绍 Rasa是一个用于构建对话 AI 的开源框架&#xff0c;主要用于开发聊天机器人和语音助手。Rasa 提供了自然语言理解&#xff08;NLU&#xff09;和对话管理&#xff08;DM&#xff09;功能&#xff0c;使开发者能够创建智能、交互式的对话系统。 1.2…

数据驱动新时代:数据飞轮如何唤醒中台潜能

前言 随着数字化转型浪潮的不断高涨&#xff0c;数据已跃升为企业战略蓝图中不可或缺的核心资产。为了更有效地整合与利用来自内外部的海量数据资源&#xff0c;众多企业纷纷着手构建数据中台&#xff0c;以期实现数据的集中管理、高效共享以及基于数据的精准业务决策。然而&a…

低代码开发平台系统架构概述

概述 织信低代码开发平台&#xff08;产品全称&#xff1a;织信Informat&#xff09;是一款集成了应用设计、运行与管理的综合性平台。它提供了丰富的功能模块&#xff0c;帮助用户快速构建、部署和维护应用程序。织信低代码平台通过集成丰富的功能模块&#xff0c;为用户提供…

构建 LLM 应用程序时经常遇到的高级概念的快速指南

使用案例 数据支持的 LLM 应用程序有无数的用例&#xff0c;但大致可以分为四类&#xff1a; 结构化数据提取 Pydantic 提取器允许您指定要从数据中提取的精确数据结构&#xff0c;并使用 LLM 以类型安全的方式填充缺失的部分。这对于从 PDF、网站等非结构化来源中提取结构化…

cdr怎么画虚线?

虚线是以点或者短线画成的断续的线&#xff0c;多用于几何图形或者标记。我们在平常学习工作中经常使用标记的方式。根据国标制图规定 机械制图 图样画法 图线规定&#xff0c;技术图样中&#xff0c;主要使用细虚线和粗虚线两种&#xff0c;细虚线用以表示不可见棱边线和不可见…

使用高版本nodej报错:node: /lib64/libm.so.6: version `GLIBC_2.27‘ not found

如果要更新GLIBC_2.27会很繁琐&#xff0c;且耗时较长&#xff0c;所以建议下载带glibc的版本的nodejs 解决方案&#xff1a;下载带glibc的版本安装&#xff0c;如果是使用nvm则解压到对应的版本控制路径 我使用的版本是v20.16.0&#xff1a;Index of /download/release/v20.1…

apk反编译修改教程系列-----修改apk 去除软件加固状态 实例操作步骤解析_1【二十七】

上期博文我们基本了解了apk的一些加固方面的常识。了解了加固的一些手段与 列举了加固检测的方法。其实对于初学者来说。这些常识了解一下即可。具体还是要实际应用。今天将陆续以实例操作来演示有些apk应用去加固的步骤。尽量步骤详细到每一步方便对照操作。 通过博文了解 1…

SD-WAN如何保障企业数据安全?

SD-WAN&#xff08;软件定义广域网&#xff09;作为一种现代化网络解决方案&#xff0c;不仅能够优化和管理广域网的连接&#xff0c;还集成了一系列安全功能&#xff0c;帮助企业保护其数据安全。以下将详细介绍SD-WAN如何有效保障企业数据安全的机制。 在采用SD-WAN技术之前&…

杭州等保测评揭秘:数据安全如何成为企业的“一道锁”

在数字化时代&#xff0c;数据安全已成为企业和机构面临的重要挑战。杭州作为科技创新的前沿城市&#xff0c;积极推进信息安全建设&#xff0c;其中等保测评&#xff08;等级保护测评&#xff09;成为保障数据安全的重要手段。 等保测评是依据《信息安全等级保护管理办法》对…

进程的重要函数

进程的重要函数: fork函数 了解fork函数 通过调用fork()函数&#xff0c;则会产生一个新的进程。调用fork()函数的进程叫做 父进程&#xff0c;产生的新进程则为子进程。 其编码过程: 1.函数功能: 函数头文件 #include <sys/types.h> #include <unistd.h> 函数…

AI绘画Stable Diffusion 自制素材工具: layerdiffusion插件—你的透明背景图片生成工具

大家好&#xff0c;我是灵魂画师向阳 今天给大家分享一款AI绘画的神级插件—LayerDiffusion。 Layerdiffusion是一个用于stable-diffusion-webui 的透明背景生成&#xff08;不是生成图再工具扣图&#xff0c;是直接生成透明背景透明图像&#xff09;插件扩展&#xff0c;它可…

C++ STL全面解析:六大核心组件之一----迭代器(STL进阶学习)

目录 迭代器&#xff08;iterator&#xff09; 迭代器的分类 迭代器的使用 创建迭代器 迭代器的基本操作 使用迭代器遍历容器 迭代器的有效性和安全性 迭代器的类型 迭代器与算法 迭代器设计思维 迭代器的本质 文件 mylist-iter.h 文件 mylist-iter-test.cpp 迭代…

多线程学习篇三:共享带来的问题及解决方案

1. 共享带来的问题 1.1 案例演示 两个线程对初始值为 0 的静态变量一个做自增&#xff0c;一个做自减&#xff0c;各做 5000 次&#xff0c;结果是 0 吗&#xff1f; Slf4j(topic "c.Sync01") public class Sync01 {private static int COUNTER 0;public static…

一次渲染十万条数据:前端技术优化(上)

今天看了一篇文章&#xff0c;写的是一次性渲染十万条数据的方法&#xff0c;本文内容是对这篇文章的学习总结&#xff0c;以及知识点补充。 在现代Web应用中&#xff0c;前端经常需要处理大量的数据展示&#xff0c;例如用户评论、商品列表等。直接渲染大量数据会导致浏览器性…

【C++登堂入室】类和对象(下)

目录 一、 再谈构造函数 1.1 构造函数体赋值 1.2 初始化列表 1.3 explicit关键字 二、static成员 2.1 概念 2.2 特性 三、友元函数 3.1 友元函数 3.2 友元类 四、内部类 五、 再次理解类和对象 结尾 一、 再谈构造函数 1.1 构造函数体赋值 在创建对象时&#xf…

【C++】多态的认识和理解

个人主页 文章目录 ⭐一、多态的概念&#x1f384;二、多态的定义及实现1.多态的构成2.实现多态的条件3.虚函数的概念4.虚函数的重写和覆盖5.析构函数的重写6.协变7.override和 final关键字8.重载、重写/覆盖、隐藏这三者的区别 &#x1f3e0;三、纯虚函数和抽象类的关系&#…