当前位置: 首页 > news >正文

C++日期类的基本实现

前言

对于许多出初学C++的同学来说首先接触的第一个完整的类便是日期类,这个类能有效的帮助我们理解C++中有关类的初始化以及重载的相关知识,帮助我们轻松上手体验C++的魅力。

文章目录

  • 前言
  • 一、日期类整体初概
  • 二、构造
    • 2.1 判断日期是否合法
    • 2.2 构造函数
  • 三、关系判断
    • 3.1 大于(>)运算符
    • 3.2 等于(=)运算符
    • 3.3 其余运算符重载
  • 四、日期的加减运算
    • 4.1 +/+=运算符
    • 4.2 -/-=运算符
    • 4.3 日期相减
    • 4.4 推算当日星期
  • 五、前置++与后置++运算符
    • 5.1 前置++运算符
    • 5.2 后置++运算符
  • 六、流插入和流提取操作符重载

一、日期类整体初概

完成一个类,我们首先需要了解这个类需要完成什么任务,需要哪些函数来进行实现,以下是一个日期类的模板框架。

class Date
{//检查日期合法bool CheckDate();//获取每月天数int GetMonthDay(int year, int month);//构造函数Date(int year = 1900, int month = 1, int day = 1);//关系判断操作符重载bool operator>(const Date& d1);bool operator== (const Date& d2);bool operator>=(const Date& d1);bool operator<(const Date& d1);bool operator<=(const Date& d1);bool operator!=(const Date& d1);//日期类的加减操作Date& operator +=(int day);Date operator +(int day);Date& operator-=(int day);Date operator-(int day);//日期减去日期int operator- (const Date& d);//计算当前天数为星期几void WeekDay();//前置、后置操作符Date& operator++();Date operator++(int);Date& operator--();Date operator--(int);//流插入和流提取操作符重载friend ostream& operator<<(ostream& out, const Date& d);friend istream& operator>>(istream& in, Date& d);
};

二、构造

在确认基本框架后,第一步是为我们的自定义类创建一个合适的构造函数,对于日期类而言,我们则需要在最开始实例化类的时候对日期进行一个判断,判断日期的合法性,例如年份大于1,月份在1-12之间,天数在对于的月份天数之内,具体的是实现如下:

2.1 判断日期是否合法

//获取当前月份的日期
int GetMonthDay(int year, int month)
{static int days[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };int day = days[month];if (month == 2&& ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))){day += 1;}return day;
}// 检查日期是否合法
bool CheckDate()
{if (_year < 1 || _month>13 || _month < 1 || _day<1 || _day>GetMonthDay(_year, _month))return false;return true;
}

2.2 构造函数

Date(int year=1900,int month=1,int day=1){_year = year;_month = month;_day = day;//检查生成的日期是否非法if (!CheckDate()){cout << "日期非法:" ;Print();//退出程序,正常退出exit(0),非法退出exit(非0);exit(-1);}}

三、关系判断

3.1 大于(>)运算符

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

3.2 等于(=)运算符

bool operator== (const Date& d2)
{return _year == d2._year&& _month == d2._month&& _day == d2._day;
}

3.3 其余运算符重载

在上面我们实现了 > 、 = 两个运算符重载。为了方便和提高可读性,对于剩下的>=、< 、 <= 、!= 这四个运算符我们可以复用的方式实现,利用> 、 = 两个运算符的逻辑组合来进行实现。

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

四、日期的加减运算

4.1 +/+=运算符

思路上我们选择一个日期加上具体天数之后,采取逐一加天数的方式,每次加完之后进行判断,当前天数是否大于当月天数,同时当月数进一的时候判断当前月数是否大于十二,依次进位。

Date operator +(int day)
{//如果day 是负数 调用-操作符重载if (day < 0){return *this - (-day);}Date d1(*this);//直接加到_day上,直到_day合法。d1._day += day;while (d1._day > GetMonthDay(d1._year, d1._month)){d1._day -= GetMonthDay(d1._year, d1._month);++d1._month;if (d1._month == 13){d1._month = 1;d1._year++;}}return d1;
}// 直接复用 "+" 运算符即可
Date& operator +=(int day)
{*this = *this + day;return *this;
}

4.2 -/-=运算符

思路上和日期加天数是一样的,但是不同的地方在于,当前天数小于1时,我们采取月份减一的方式,依次借位。

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 operator-(int day)
{Date temp(*this);temp -= day;return temp;
}

4.3 日期相减

我们在上面已经实现了日期加上天数以及两个日期之间是否相等的判断,在此可以直接复用,默认前一个日期大于后一个日期,将较小的日期天数逐次加一,当加到和较大天数相等时,此时加一的次数就是日期之间相差的天数。

//两个日期相减
int  operator- (const Date & d)
{//先假设 *this > dint flag = 1;Date max = *this;Date min = d;if (*this < d){max = d;min = *this;flag = -1;}int count = 0;while (min != max){	++min;++count;}return count * flag;
}

4.4 推算当日星期

由于1900年1月1日正好是周一,因此我们计算某个日期减去1900年1月1日得到的天数并对七取模即可。

//判断当前日期是周几
void WeekDay( )
{Date statr(1900, 1, 1);//求相差的天数int n = *this - statr;//5相当于是周6int weekday = 0;weekday += n;cout << "周" << weekday % 7 + 1 << endl;
}

五、前置++与后置++运算符

对于前置++和后置++运算符两者之间似乎操作数一样,但是不同之处在于后置++重载时有一个操作数,同时需要注意后置++运算符返回值应是修改前的值,对于 “–” 运算符与 “++“ 运算符基本一致,不在此列出。

5.1 前置++运算符

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

5.2 后置++运算符

Date operator++(int)
{Date temp(*this);*this += 1;return temp;
}

六、流插入和流提取操作符重载

相比于其他的运算符,流插入和流提取则有一丝不同,我们知道运算符重载时默认第一位是 this 指针,但是流插入和流提取第一个操作数明显是流插入运算符或流提取运算符,因此必须将其设为全局函数

此时又会遇到另一个问题,全局函数如何访问类的私有成员,此时就需提前将其声明为友元函数在进行重载

ostream& operator<<(ostream& out,const Date& d) 
{out << d._year << '/' << d._month << '/' << d._day;return out;
}istream& operator>>(istream& in, Date& d)
{in >> d._year >> d._month >> d._day;//检查输入格式是否正确assert(d.CheckDate());return in;
}

相关文章:

C++日期类的基本实现

前言 对于许多出初学C的同学来说首先接触的第一个完整的类便是日期类&#xff0c;这个类能有效的帮助我们理解C中有关类的初始化以及重载的相关知识&#xff0c;帮助我们轻松上手体验C的魅力。 文章目录 前言一、日期类整体初概二、构造2.1 判断日期是否合法2.2 构造函数 三、…...

第六章:数据结构与算法-part3:数据结构算法提升

文章目录 一、排序算法1.1 插入排序1、直接插入排序2、折半插入排序3、希尔排序 1.2、交换排序法1、起泡排序2、快速排序 1.3 选择类排序1、简单选择排序 二、业务逻辑算法设计2.1 基本概念和术语2.2 静态查找表2.3、有序表的查找 一、排序算法 排序是数据处理过程中经常使用的…...

keras深度学习框架通过卷积神经网络cnn实现手写数字识别

昨天通过keras构建简单神经网络实现手写数字识别&#xff0c;结果在最后进行我们自己的手写数字识别的时候&#xff0c;准确率堪忧&#xff0c;只有60%。今天通过卷积神经网络来实现手写数字识别。 构建卷积神经网络和简单神经网络思路类似&#xff0c;只不过这里加入了卷积、池…...

Springboot启动异常 Command line is too long

Springboot启动异常 Command line is too long Springboot启动时直接报异常 Command line is too long. Shorten command line for xxxxxApplication or also for Spring Boot default解决方案: 修改 SystemApplication 的 Shorten command line&#xff0c;选择 JAR manife…...

PXE 装机(五十)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、PXE是什么 二、PXE的组件 三、配置vsftpd 四、配置tftp 五、准备pxelinx.0文件、引导文件、内核文件 ​六、配置dhcp 七、创建default文件 八、配置pxe无人值守…...

C++ 虚函数与纯虚函数

目录 1. 虚函数 2. 纯虚函数 C 中的虚函数和纯虚函数都是实现多态的重要机制。多态可以让不同的对象以相同的方式进行操作&#xff0c;从而简化代码的编写和维护。 1. 虚函数 虚函数是一种在基类中声明的函数&#xff0c;可以在派生类中进行重写。在运行时&#xff0c;根据对…...

警告:Provides transitive vulnerable dependency maven:org.yaml:snakeyaml:1.30

1. 警告 SpringBoot 的 validation 依赖包含有易受攻击的依赖 snakeyaml。 警告信息如下&#xff1a; Provides transitive vulnerable dependency maven:org.yaml:snakeyaml:1.30 意思是&#xff1a;提供了可传递的易受攻击依赖 maven:org.yaml:snakeyaml:1.30 2. 警告示例 …...

中文命名实体识别

本文通过people_daily_ner数据集&#xff0c;介绍两段式训练过程&#xff0c;第一阶段是训练下游任务模型&#xff0c;第二阶段是联合训练下游任务模型和预训练模型&#xff0c;来实现中文命名实体识别任务。 一.任务和数据集介绍 1.命名实体识别任务 NER&#xff08;Named En…...

WPF CommunityToolkit.Mvvm Messenger通讯

文章目录 环境WeakReferenceMessenger方法介绍无回调订阅发送Token区分有回调订阅发送 环境 CommunityToolkit.Mvvm Messenger 十月的寒流: 如何使用 CommunityToolkit.Mvvm 中的 Messenger 来进行 ViewModel 之间的通信 WeakReferenceMessenger 我这里只讲简单的弱Messenger…...

【杂言】写在研究生开学季

这两天搬进了深研院的宿舍&#xff0c;比中南的本科宿舍好很多&#xff0c;所以个人还算满意。受台风 “苏拉” 的影响&#xff0c;原本的迎新计划全部打乱&#xff0c;导致我现在都还没报道。刚开学的半个月将被各类讲座、体检以及入学教育等活动占满&#xff0c;之后又是比较…...

渗透测试漏洞原理之---【任意文件读取漏洞】

文章目录 1、概述1.1、漏洞成因1.2、漏洞危害1.3、漏洞分类1.4、任意文件读取1.4.1、文件读取函数1.4.2、任意文件读取 1.5、任意文件下载1.5.1、一般情况1.5.2、PHP实现1.5.3、任意文件下载 2、任意文件读取攻防2.1、路径过滤2.1.1、过滤../ 2.2、简单绕过2.2.1、双写绕过2.2.…...

合宙Air724UG LuatOS-Air LVGL API控件-图片 (Image)

图片 (Image) 图片IMG是用于显示图像的基本对象类型&#xff0c;图像来源可以是文件&#xff0c;或者定义的符号。 示例代码 -- 创建图片控件 img lvgl.img_create(lvgl.scr_act(), nil) -- 设置图片显示的图像 lvgl.img_set_src(img, "/lua/luatos.png") -- 图片…...

仿京东 项目笔记2(注册登录)

这里写目录标题 1. 注册页面1.1 注册/登录页面——接口请求1.2 Vue开发中Element UI的样式穿透1.2.1 ::v-deep的使用1.2.2 elementUI Dialog内容区域显示滚动条 1.3 注册页面——步骤条和表单联动 stepsform1.4 注册页面——滑动拼图验证1.5 注册页面——element-ui组件Popover…...

Spark与Flink的区别

分析&回答 &#xff08;1&#xff09;设计理念 1、Spark的技术理念是使用微批来模拟流的计算,基于Micro-batch,数据流以时间为单位被切分为一个个批次,通过分布式数据集RDD进行批量处理,是一种伪实时。 2、Flink是基于事件驱动的&#xff0c;是面向流的处理框架, Flink基于…...

未来智造:珠三角引领人工智能产业集群

原创 | 文 BFT机器人 产业集群是指产业或产业群体在地理位置上集聚的现象&#xff0c;产业集群的研究对拉动区域经济发展&#xff0c;提高区域产业竞争力具有重要意义。 从我国人工智能产业集群形成及区域布局来看&#xff0c;我国人工智能产业发展主要集聚在京津冀、长三角、…...

【Unity db】sqlite

背景 最近使用unity&#xff0c;需要用到sqlite&#xff0c;记录下使用过程 需要的动态库 Mono.Data.Sqlite.dll&#xff0c;这个文件下载参考下面链接 SqliteConnection的Close和Open 连接的概念&#xff1a; 在数据库编程中&#xff0c;连接是一个重要的概念&#xff0c…...

Linux 指令心法(四)`touch` 创建一个新的空文件

文章目录 命令的概述和用途命令的用法命令行选项和参数的详细说明命令的示例命令的注意事项或提示 命令的概述和用途 touch 是一个用于在 Linux 和 Unix 系统中创建空文件或更改现有文件的访问和修改时间的命令。如果指定的文件不存在&#xff0c;touch会创建一个新的空文件&a…...

分类算法系列②:KNN算法

目录 KNN算法 1、简介 2、原理分析 数学原理 相关公式及其过程分析 距离度量 k值选择 分类决策规则 3、API 4、⭐案例实践 4.1、分析 4.2、代码 5、K-近邻算法总结 &#x1f343;作者介绍&#xff1a;准大三网络工程专业在读&#xff0c;努力学习Java&#xff0c;涉…...

12. 微积分 - 梯度积分

Hi,大家好。我是茶桁。 上一节课,我们讲了方向导数,并且在最后留了个小尾巴,是什么呢?就是梯度。 我们再来回看一下但是的这个式子: [ f x f y...

Large Language Models and Knowledge Graphs: Opportunities and Challenges

本文是LLM系列的文章&#xff0c;针对《Large Language Models and Knowledge Graphs: Opportunities and Challenges》的翻译。 大语言模型和知识图谱&#xff1a;机会与挑战 摘要1 引言2 社区内的共同辩论点3 机会和愿景4 关键研究主题和相关挑战5 前景 摘要 大型语言模型&…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

深度学习水论文:mamba+图像增强

&#x1f9c0;当前视觉领域对高效长序列建模需求激增&#xff0c;对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模&#xff0c;以及动态计算优势&#xff0c;在图像质量提升和细节恢复方面有难以替代的作用。 &#x1f9c0;因此短时间内&#xff0c;就有不…...

【C++】纯虚函数类外可以写实现吗?

1. 答案 先说答案&#xff0c;可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...

渗透实战PortSwigger靶场:lab13存储型DOM XSS详解

进来是需要留言的&#xff0c;先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码&#xff0c;输入的<>当成字符串处理回显到页面中&#xff0c;看来只是把用户输…...

C++_哈希表

本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、基础概念 1. 哈希核心思想&#xff1a; 哈希函数的作用&#xff1a;通过此函数建立一个Key与存储位置之间的映射关系。理想目标&#xff1a;实现…...