用C++实现Date类

news2025/1/19 19:30:06

Date类

 判断 大于 小于 等于 等等运算符重载函数

我们先实现一个  >  的运算符重载,然后再实现一个 ==  的运算符重载: 

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

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

那接下来我们就可以调用这个两个 重载函数,来实现其他的 函数:
例如:< 就是 !>  &&   !==   :

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);
}

需要注意的是:上述后面 运算符重载函数 的实现技巧不仅仅可以用在 Date 简单简单类当中,因为后序的技巧只是在调用 对应的重载函数。所以这种技巧在如何类当中都可以使用。

 其他功能函数实现

 日期 +  天数 计算日期函数

 首先确定的是每一个月的 天数不统一,而且有平年和闰年的区分2月的天数,所以我们先写一个函数来获取某一个月的 天数:
创建一个数组,下标 代表 月份,元素的值代表 这个月的天数:

static int array[] = {0,31,28,31,30,31,31,30,31,31,30,31,30,31};

 直接把这个数组写在静态区,因为这个函数会被调用很多次,每次都需要创建这个数组的话很麻烦,所以我们直接创建静态的。

然后是判断闰年:
 

if(month == 2 && ((year % 4 == 0) || (year % 100 != 0) || (year % 400 == 0)))
{
    return 29;
}
else
{
    return array[month];
}

当我们拿到 一个月的天数的时候,我们就可以直接进行操作了,我们先直接把 需要加的天数直接加载 日期 的 _day 成员中,然后判断此时是否超出当月的天数,如果超出,_day 就减掉 当月的天数,_month++,然后再次判断,如果再超,就再减,如果不超说明就计算计算完成。如果上述月超了13,那么_year++。

 下述代码的实现是有问题的:

Date Date::operator+(int day)
{
	_day += day;
	while (_day > GetMonthDate(_year, _month))
	{
		_day -= GetMonthDate(_year, _month);
		_month++;
		if (_month >= 13)
		{
			_month = 1;
			_year++;
		}
	}
	return *this;
}

 这样写有一个问题,如下图:

 我们只写了 d1 + 100 ,但是我们发现 d1 被修改了,其实是我们上述直接 对 _day 进行修改,我们应该把计算好的值作为函数的返回值。

 所以,我们上诉实现的其实不是 +  ,其实是 += :

Date Date::operator+=(int day)
{
	_day += day;
	while (_day > GetMonthDate(_year, _month))
	{
		_day -= GetMonthDate(_year, _month);
		_month++;
		if (_month >= 13)
		{
			_month = 1;
			_year++;
		}
	}
	return *this;
}

接下来我们对这个函数进行修改,实现 + 的重载:
 

Date Date::operator+(int day)
{
    Date tmp(*this);

	tmp->_day += day;
	while (tmp->_day > GetMonthDate(_year, _month))
	{
		tmp->_day -= GetMonthDate(_year, _month);
		tmp->_month++;
		if (tmp->_month >= 13)
		{
			tmp->_month = 1;
			tmp->_year++;
		}
	}
	return tmp;
}

我们在 + 重载函数中创建一个 Date对象-tmp,然后把 当前对象拷贝给 这个tmp 对象,我们修改就修改这个 tmp 对象当中的 值,最后返回这个 tmp 就行了。

输出:

 我们来看这个场景,当我们调用如下函数的时候,d3 是调用拷贝构造函数在创建,还是通过赋值来创建呢?

	Date d3 = d1 + 100;

其实是 调用构造函数 来创建,因为此时编译器会做处理,把这个代码变成 如下来进行执行:

Date d3(d1 + 100);

+ 重载还可以这样写:

Date Date::operator+(int day)
{
	Date tmp(*this);

	tmp += day;

	return tmp;
}

可以服用 += 重载函数。

前置++ 和后置++ 的实现

// 前置++
Date& Date::operator++()
{
	*this += 1;
	return *this;
}

// 后置++
Date Date::operator++(int)
{
	Date tmp(*this);
	*this += 1;
	return tmp;
}

需要注意的是,前置后置 是 通过参数来构成重载,如 d1++;

  • ++d1 会转换为 d1.operator++()  
  • d1++ 会转换成 d1.operator(0) 

 上述增加的int 不是为了接收具体的值,仅仅是为了占位,跟前置结点构成函数重载。

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

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

相关文章

教你如何通过内网穿透轻松实现PL/SQL远程连接Oracle数据库【内网穿透】

文章目录 前言1. 数据库搭建2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射 3. 公网远程访问4. 配置固定TCP端口地址4.1 保留一个固定的公网TCP端口地址4.2 配置固定公网TCP端口地址4.3 测试使用固定TCP端口地址远程Oracle 转发自CSDN远程穿透的文章&#xff1a;公网远程连…

【PLC】贝加莱PLC理论及操作年度培训

最近在进行PLC培训&#xff0c;主要是贝加莱PLC产品的学习&#xff0c;学习了上下位机的一些基本操作&#xff0c;能够进行一些简单的实践&#xff0c;最后顺利通过年度考核。 0 引言 PLC&#xff1a;可编程逻辑控制器&#xff0c;由CPU、存储器、输入输出接口、电影以及外部设…

【unity专题篇】—GUI(IMGUI)思维导图详解

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…

企业关键数据资产如何保护?腾讯安全联合“数据安全推进计划”落地主题沙龙

4月26日&#xff0c;腾讯安全联合中国信通院“数据安全推进计划”共同在深圳举办了数据安全研讨会&#xff0c;共同探讨新形势下如何让企业关键数据资产更安全。中国信息通信研究院云计算与大数据研究所高级业务主管龚诗然、腾讯云安全总经理李滨、炼石网络创始人兼CEO白小勇、…

【Vue3学习笔记1】一个清单应用帮你入门Vue.js

Vue 目前已经是国内最流⾏的前端框架之⼀&#xff0c;Vue 3 带来的诸多优化更是让前端圈迎来了新的潮流&#xff0c;比如&#xff1a; 基于 Proxy 的全新响应式实现&#xff1b; Composition API <script setup> 组织代码的更优方式&#xff1b; 更有料的 TypeScript 支…

关于C++的线程操作 | 双检锁与智能指针接口使用

文章目录 thread对象的构造this_threadconstructmutexref 用lambda表达式构造thread线程串行比并行快&#xff1f;CAS&#xff08;atomic类&#xff09;timed_mutexlock_guard,unique_guard&#xff0c;手动控制生命周期,为什么要使用条件变量不用条件变量带来的问题&#xff1…

【python基础语法三】列表,元组,集合,字典相关操作

列表的相关操作 1. 列表的拼接 (同元组) lst1 ["hello","world"] lst2 ["hello","python"] res lst1 lst2 print(res) # ["hello","world","hello","python"]2. 列表的重复 (同元组) …

二、搭建MyBatis采用xml方式,验证CRUD(增删改查操作)

文章目录 二、搭建MyBatis采用xml方式&#xff0c;验证CRUD&#xff08;增删改查操作&#xff09;2.1 开发环境2.2 创建maven工程2.3 创建User实体2.4 创建MyBatis的核心配置文件2.5 创建mapper接口2.6 创建MyBatis的映射文件2.7 通过junit测试功能 二、搭建MyBatis采用xml方式…

三、MyBatis核心配置文件详解

文章目录 三、MyBatis核心配置文件详解 三、MyBatis核心配置文件详解 application.properties server.port8018 jdbc.drivercom.mysql.cj.jdbc.Driver jdbc.urljdbc:mysql://192.168.31.20:3306/litemall jdbc.usernameroot jdbc.password123456详情请看mybatis-config.xml配置…

Linux Ansible-Jinjia2模板

目录 jinja2模板语法 部署jinja2模板 jinja2逻辑表达式 jinja2是基于Python书写的模块引擎&#xff0c;ansible通常会使用jinja2模块结合template模块来修改被管理主机的配置文件 一般使用ansible的事实变量或魔法变量编写一个jinja2模板文件&#xff0c;然后使用template模…

Navicat安装教程和评测

Navicat是一款功能强大的数据库管理软件&#xff0c;拥有丰富的功能和易于使用的界面&#xff0c;因此价格相对较高。此外&#xff0c;Navicat还提供了多种数据库类型的支持&#xff0c;包括MySQL、Oracle、PostgreSQL等&#xff0c;每种数据库类型都需要花费开发人员大量的时间…

Qt QWidget 独立窗口抗锯齿圆角的一个实现方案(支持子控件)

QWidget独立窗口抗锯齿圆角窗口的一个实现方案 由于 QWidget::setMask 接口设置圆角不支持抗锯齿&#xff0c;所以通常会使用透明窗口加圆角背景&#xff0c;但圆角背景不能满足对子控件的裁剪&#xff0c;子控件与圆角区域重叠的部分还是能显示出来。当然对于大多数窗口&…

使用Git和GitHub完成团队项目开发

前提 拥有自己的GitHub账号项目组组长已经创建好了 一个远程仓库能够科学上网安装了Git软件 基础步骤 该内容分为两个部分&#xff0c;分别为团队协作者&#xff08;项目成员&#xff09;和团队组织者&#xff08;项目组长&#xff09;&#xff0c;我们首先来介绍作为项目成员…

BitoAI:新型AI编码助手,支持GPT-4

在之前的文章中&#xff0c;小编带大家分享体验过OpenAI的Cursor代码生成器、Codeium编程助手、亚马逊的CodeWhisperer。大家也都非常踊跃的在评论区分享了体验的感受及遇到的问题。 而最近又出现了一款新型编程助手BitoAI。今天的主要内容就是给大家介绍它&#xff0c;号称 I…

栈的顺序存储结构与操作 题目编号:457

题目描述 请你定义一个顺序栈&#xff0c;可以对顺序栈进行“将某个元素入栈”、“弹出栈顶元素”、“取栈顶元素&#xff08;不删除&#xff09;”、“判断栈是否为空”、“清空栈”等操作。键盘输入一些命令&#xff0c;可以执行上述操作。本题中&#xff0c;顺序栈元素为字…

宝塔面板主题模板修改详细使用教程

宝塔面板主题模板修改详细使用教程 宝塔面板目前没有完善的主题、语言包功能&#xff0c;因此资源均采用覆盖的方式使用。 使用前请确保面板版本与资源包版本一致&#xff0c;新版本没有资源可以使用 降级版本 的方式使用。 原创资源均采用只修改少量静态文件的方式&#xff0c…

Portainer自定义设置默认的用户名密码

文章目录 Portainer介绍用户密码问题解决一半未完待续 Portainer介绍 Portainer是一款轻量级的Docker管理Web界面&#xff0c;它可以让用户方便地管理和部署Docker容器&#xff0c;管理Docker Swarm集群等用户可以通过Portainer轻松完成基于Docker的应用部署、镜像管理、容器监…

三台Windows服务器搭建RabbitMq集群及镜像队列

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、RabbitMq是什么&#xff1f;二、RabbitMq集群搭建步骤1.环境说明2.RabbitMQ 安装3.RabbitMQ 集群搭建4.RabbitMQ镜像队列 总结 前言 消息中间件-RabbitMq集…

Ubuntu 23.04 安装 Harbor

Ubuntu 23.04 安装 Harbor 安装 Docker CE配置 tls 证书配置 docker 信任自签名证书下载和安装 Harbor设置 Harbor 开机启动验证 安装 Docker CE sudo apt-get remove docker docker-engine docker.io containerd runcsudo apt-get update -y sudo apt-get install -y \ca-cer…

shell脚本----循环语句for

文章目录 一、echo命令二、for循环三、continue和break 一、echo命令 常见转义字符&#xff1a; 转义符号含义-n表示不换行输出\e输出转义字符&#xff0c;将转义后的内容输出到屏幕上\b转义后相当于按退格键&#xff0c;但前提是b后面存在字符: b表示删除前一个字符&#xf…