【C++ 基础篇:25】:【重要模板】C++ 算术(赋值)运算符重载及自增自减运算符重载【以 Date 日期类为例】

news2024/11/18 3:32:55

系列文章说明

本系列 C++ 相关文章 仅为笔者学习笔记记录,用自己的理解记录学习!C++ 学习系列将分为三个阶段:基础篇、STL 篇、高阶数据结构与算法篇,相关重点内容如下:

  1. 基础篇类与对象(涉及C++的三大特性等);
  2. STL 篇学习使用 C++ 提供的 STL 相关库
  3. 高阶数据结构与算法篇手动实现自己的 STL 库设计实现高阶数据结构,如 B树、B+树、红黑树等。

学习集:

  • C++ 入门到入土!!!学习合集
  • Linux 从命令到网络再到内核!学习合集

文章目录

  • 系列文章说明
  • 前言
  • 一、C++ 算术(赋值)运算符重载
    • 1. 说明
    • 2. += / -= 号运算符重载【以 Date 日历类为例】
      • 2.1 设计思路
      • 2.2 解决:闰年问题(计算规则及起源介绍)
      • 2.3 月份天数问题
      • 2.4 += 或 -= 运算符的重载设计与实现
      • 2.5 测试图例结果
    • 3. + 或 - 运算符重载
      • 3.1 + 运算符的重载设计及实现及测试
      • 3.2 - 运算符的重载设计及实现及测试
    • 4. 关于 * 、/、*=、/= 重载设计与实现
  • 二、C++ 自增自减运算符重载
    • 1.基本认识
    • 2.自增自减运算符重载实现
      • 2.1 前置 ++ 或 -- 运算符重载实现
      • 2.2 后置 ++ 或 -- 运算符重载实现
    • 2.3 测试结果图例
  • 相关文章


前言

  • 对于类的基本学习已经到了一定的阶段,故最近几篇文章笔者将和大家分享的内容是:《运算符重载小专题》!目前已更新:关系运算符的重载(点击跳转)输入输出运算符重载(点击跳转) ,解决的自定义类型 / 对象的比较与输入输出问题!
  • 本篇文章中,笔者将与大家分享的是 自定义类型 / 对象 的运算问题!即:自增自减运算符重载及算术运算符重载

一、C++ 算术(赋值)运算符重载

1. 说明

本文中将以 +、-、+=、-= 为例,设计实现算术(赋值)运算符重载!【注意:在此前运算符重载说明篇中,提及过:运算符重载不能改变其本身意义!】


2. += / -= 号运算符重载【以 Date 日历类为例】

符号含义

  • +=:加且赋值运算符,把右边操作数加上左边操作数的结果赋值给左边操作数!
  • -=:减且赋值运算符,把左边操作数减去右边操作数的结果赋值给左边操作数

对于我们的 Date 日期类而言,一般提供的接口会有:推算当前日期加减多少天后的日期问题!
此时就出现,如:2023-6-16 += 或 + 15天 之类的运算情形!显然使用原有的运算符是无法进行计算的!(如下图)

在这里插入图片描述


2.1 设计思路

故,我们需要重载我们的运算符!由于 + 或 - 可以基于 += 或 -= 来实现,因此笔者优先实现对 += / -= 的重载


实现设计思路:

  1. 参数问题:显然需要传递一个天数用于递推的运算。该值不需要改变,故可以使用 const 修饰。
  2. 日期迭代计算问题:由于涉及到日期的更迭,我们需要考虑的每个月的天数问题!以及可能出现闰年二月的情形

2.2 解决:闰年问题(计算规则及起源介绍)

关于:闰年问题!

  • 判断闰年的方式(1582年后的计算准则):该年可以被 400 整除 或 概念可以被 4 整除但不能被 100 整除,如:1900年不是闰年!

关于闰年起源问题:(以上闰年计算法则是1582年后的计算规则!)

  • 1582年以来公历的置闰规则:
  • 普通闰年:公历年份是4的倍数,且不是100的倍数的,为闰年(如2004年、2020年等就是闰年)。
  • 世纪闰年:公历年份是整百数的,必须是400的倍数才是闰年(如1900年不是闰年,2000年是闰年)。
  • 1582年以前的惯例:四年一闰;如果公元 A 年的 A(正数)能被 4 整除,那么它就是闰年;如果公元前B年的B(正数)除以4余1,那么它也是闰年。

闰年判断函数实现(如下):

  • 参数:年份
  • 返回值:是 / 否
/* 闰年判断 */
bool IsLeapYear(int year) {
	return (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
}

2.3 月份天数问题

为了方便计算,笔者单独把获取月份天数设计为一个函数!


设计思路:

  • 参数:年份、月份
  • 返回值:int 类型(天数)
  • 特殊处理:二月份默认设定为 28 天,遇到闰年,即返回值 +1;
  • 优化处理:由于获取月份天数可能使用频率较高,建议使用数组存储数据(设计如下:注意注释解释),并设定为静态数组!(避免每次调用函数新建数组的性能开销!)。

代码实现如下:

/* 获取月份天数 */
int GetMonthDay(int year, int month) {
	/* 设置为静态数组提升效率 */
	/* 数组大小设置为 13 ,即为了直接使用 days[month] 访问到数据 */
	static int days[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	
	if (month == 2 && IsLeapYear(year)) {
		return days[month] + 1;
	}
	return days[month];
}

2.4 += 或 -= 运算符的重载设计与实现

设计思路(注意点):


  1. 基本思路:总是在第几日上增加 / 减少天数实现推算日期,过程中注意判断月份更迭与年份更迭!
  2. 参数:推算所传递的天数。
  3. 返回值:日期的引用!
  4. 其他细节见注释!

+= 运算符重载(实现如下)

/* += 赋值运算符重载 */
Date& Date::operator += (const int day) {
	_day += day;									/* 直接递增天数 */
	while (_day > GetMonthDay(_year, _month)) {		/* 日期“合法性”判断 */
		/* 若:天数大于本月的固定天数,则 天数 - 本月天数,并将月份 + 1 */
		_day -= GetMonthDay(_year, _month);			/* 天数更跌 */
		_month += 1;								/* 月份更迭 */
		if (_month == 13) {							/* 年份更迭 */
			_month = 1;
			_year++;
		}
	}
	return *this;
}

-= 运算符重载(实现如下)

Date& Date::operator -= (const int day) {
	_day -= day;
	while (_day < 1) {								/* 判断天数合法性 */
		if (_month == 1) {							/* 特殊点:年份更迭 */
			_month = 13;							/* 注意此处:13,为的是后续统一的月份更迭计算 */
			_year--;
		}
		_day += GetMonthDay(_year, _month - 1);
		_month--;
	}
	return *this;
}

2.5 测试图例结果

在这里插入图片描述


3. + 或 - 运算符重载

结合上一篇文章中提及,提高代码复用性,此处可以直接使用已有的 += 或 -= 实现 + 或 - 运算符的重在!

3.1 + 运算符的重载设计及实现及测试

+ 运算符重载(实现如下,注意注释提示)

  • 注意返回值:不是引用!
/* 
	在该函数中,不会去修改 Date 对象本身,
	而是返回一个新的对象,
	函数外部可以赋值给原对象或新对象!
*/
Date Date::operator+(const int day) const		
{
	// Date ret(*this);			/* 拷贝构造 */
	Date ret = *this;			
	ret += day;
	return ret;
}

在这里插入图片描述


3.2 - 运算符的重载设计及实现及测试

+ 运算符重载(实现如下,注意注释提示)

  • 注意返回值:不是引用!
/* 
	在该函数中,不会去修改 Date 对象本身,
	而是返回一个新的对象,
	函数外部可以赋值给原对象或新对象!
*/
Date Date::operator-(const int day) const		
{
	// Date ret(*this);			/* 拷贝构造 */
	Date ret = *this;			
	ret -= day;
	return ret;
}

在这里插入图片描述


4. 关于 * 、/、*=、/= 重载设计与实现

  • 关于 * 、/、*=、/= 重载设计与实现,根据前文内容,照葫芦画瓢即可!

二、C++ 自增自减运算符重载

1.基本认识

在 C/C++ 中,我们可以使用 ++ / -- 来对我们定义的数据变量进行自增自减操作!这俩运算符可谓是新人学习的噩梦,尤其是大学生期末考试试卷中,那没有任何实际意义的自增自减运算符组合求值问题。【基本使用如下图所示!】


在以往的学习中,可能大家或多或少听说过:前置自增自减 效率高于 后置自增自减。【当然在现在的编译器下肯定是几乎没有区别的,早已被优化】


已知,自增自减运算符分为:前置 和 后置,主要区别就是:

  • 前置是:优先自身运算后再参与到其他运算;
  • 后置是:先参与其他运算之后,再自身运算!

在这里插入图片描述


2.自增自减运算符重载实现

前置后置的 ++ / -- 实际使用中,我们书写就是前置和后置的区别,但是在重载的时候我们该怎么办?

  • 函数写法:使用函数重载!
  • 重载函数的区分方式使用一个参数来区别方案:前置使用无参形式,后置使用含参形式注:实际实现后,我们不需要去显示传递后置实现过程中的那个参数!编译器会自动辨别为自增自减运算符重载的区别参数】
  • 函数返回值:对象本身(引用返回)

设计代码如下(注意复用代码):

2.1 前置 ++ 或 – 运算符重载实现

  • 前置 ++ ,即先 +1 再返回!
  • 前置 -- ,即先 -1 再返回!
/* 前置 ++ */
Date& Date::operator++()
{
	return *(this + 1);
}

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

2.2 后置 ++ 或 – 运算符重载实现

  • 后置 ++ ,即先返回,再运算!(借助:临时对象)
  • 后置 -- ,即先返回,再运算!(借助:临时对象)
/* 后置 ++ */
Date& Date::operator++(int)
{
	Date ret(*this);
	*this += 1;
	return ret;
}

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

2.3 测试结果图例

在这里插入图片描述


相关文章

1. 【C++ 基础篇:21】:friend 友元四连问:什么是友元?友元类?友元函数?什么时候用友元?
2. 【C++ 基础篇:22】:类的 const 对象 与 const 成员函数/方法 以及 类中涉及 const 的常见问题!
3. 【C++ 基础篇:23】:【重要模板】关系运算符重载的设计与实现: [ > 、 < 、 >= 、 <= 、 != 、 == ] 重载【以 Date 时间类为例】


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

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

相关文章

LabVIEW开发监测太阳能电池和损伤检测

LabVIEW开发监测太阳能电池和损伤检测 使用LabVEW监测太阳能电池的实时数据&#xff0c;利用LabVIEW实现太阳能跟踪和损伤检测。使用了太阳能电池板&#xff0c;Arduino UNO板&#xff0c;电压&#xff08;0-25V&#xff09;传感器LDR&#xff0c;温度传感器和伺服电机。Solar…

基于ubuntu20.4搭建的K8S集群新增工作节点带GPU显卡过程记录

基于ubuntu20.4搭建的K8S集群新增工作节点带GPU显卡过程记录 1、创建虚拟机引导选择efi 2、添加显卡,修改虚拟机-高级参数,添加以下两个参数 pciPassthru.64bitMMIOSizeGB:192 pciPassthru.use64bitMMIO:TRUE否则可能无法开机。 3、添加直通显卡,安装显卡驱动。 3.1、查…

Redis集群详细介绍从0开始-包括集群的Jedis开发

集群 为什么需要集群-高可用性 1、生产环境的实际需求和问题 容量不够&#xff0c;redis 如何进行扩容&#xff1f;并发写操作&#xff0c; redis 如何分摊&#xff1f;主从模式&#xff0c;薪火相传模式&#xff0c;主机宕机&#xff0c;会导致ip 地址发生变化&#xff0c;…

linuxOPS系统服务_linux文件权限管理

什么是权限 **权限&#xff1a;**在计算机系统中&#xff0c;权限是指某个计算机用户具有使用软件资源的权利。 权限的目的 文件权限的设置目的&#xff1a;是想让某个用户有权利操作文件 权限的分类 普通权限rwx 用户正常情况去操作文件所具有的权限 高级权限st 用户对某…

FPGA基础知识-任务和函数

目录 学习目标 学习内容 1.任务和函数的区别 2.任务 3.函数 学习时间 学习总结 学习目标&#xff1a; 1.理解任务和函数之间的区别。 2.理解定义任务所需的条件&#xff0c;学会任务的声明和调用。 3.理解定义函数所需的条件&#xff0e;学会函数的声明和调用。 学习…

JavaScript之ES6高级语法(四)

本文是我在学习过程中记录学习的点点滴滴&#xff0c;目的是为了学完之后巩固一下顺便也和大家分享一下&#xff0c;日后忘记了也可以方便快速的复习。 ES6高级语法(四&#xff09; 前言一、深浅拷贝1.1、浅拷贝1.2、深拷贝1.2.1、递归实现深拷贝1.2.2、js库lodash里面cloneDee…

你们软件测试面试最难的一道题是什么?

在测试面试时&#xff0c;面试官往往会出一个简单的场景让大家进行测试点设计来考察大家的测试设计能力&#xff0c;题目看似简单实则蕴藏杀机&#xff0c;测试人员需要根据自己的工作年限做出不同的回答方可过关。 如果你工作1-2年&#xff0c;那么你只需要回答功能方面的测试…

源来Intel——开放原子全球峰会

文章目录 Intel的开源之路AI领域边缘人工智能在中国的发展趋势边缘人工智能领域的挑战生态系统解决方案英特尔针对边缘人工智能的产品总结 英特尔基础软件赋能中国生态Intel : 软件优先 推动中国市场中国Linux操作系统生态Intel全力投入中国开源社区开发国产Linux厂商&#xff…

I2C中的时钟同步与仲裁

时钟同步和仲裁 在单主设备中&#xff0c;不需要时钟同步和仲裁。而在多设备时&#xff0c;多个主设备可以同时在空闲的总线上开始发送数据&#xff0c;这时就需要仲裁决定哪一个来控制总线并完成它的数据传输&#xff0c;有时候也需要时钟同步来协同设备间的工作。而这正是通过…

Android音视频开发实战02-Jni

一 JNI 1.1 什么是JNI JNI是Java Native Interface的缩写&#xff0c;是Java提供的一种机制&#xff0c;用于在Java代码中调用本地&#xff08;C/C&#xff09;代码。它允许Java代码与本地代码进行交互&#xff0c;通过JNI&#xff0c;Java应用程序可以调用一些原生库或者操作…

Maven编译常见问题收集

1、父pom里面有引入lombok依赖&#xff0c;为什么子pom有用到lombok&#xff0c;依然识别不到呢 这是因为父pom引入依赖的时候&#xff0c;把 <dependency></dependency>依赖标签&#xff0c;最外层包 在了<dependencyManagement></dependencyManagemen…

Python学了基本语法 下一步该干什么 ?

刚入门Python,学习了基本语法后&#xff0c;你可以开始编写简单的程序了。接下来&#xff0c;你可以学习Python的标准库和第三方库&#xff0c;掌握更多的编程技巧和知识&#xff0c;提高自己的编程能力。同时&#xff0c;也可以通过实践项目来巩固所学知识&#xff0c;提高自己…

web3描述以太坊与区块链之间的操作关系

好通过前面两篇文章 Web3.0概念 web3带大家简单建立区块链概念 大家开始明白 web3.0是基于区块链为基础开发的 我们讲区块链多次提到以太坊 EVM 那这个东西到底是什么呢&#xff1f; 就现在的情况来讲 从零到一去搭建一个区块链环境 那可太难了 所以 以太坊一开始 确实是做一…

关于GPT-3和GPT-4,你需要知道都在这里

友情提示 提示&#xff1a;本文约3500个文字&#xff0c;字数较长&#xff0c;可直接点击序号进入相关目录阅读字数 文章目录 友情提示前言一、什么是 GPT-3、GPT-4 和 ChatGPT&#xff1f;二、对未来的担忧三、什么时候可以用GPT4&#xff1f;四、GPT-4用在什么地方五、GPT-4能…

json_decode返回NULL

json_decode返回NULL 最近在调用某公司的API时&#xff0c;将对方返回的数据&#xff0c;使用PHP的json_decode函数解析&#xff0c;但是返回NULL,最终排查为对方传送来的json格式有误 打印$_REQUEST&#xff0c;数据结构大致如下&#xff1a; 1 2 3 4 5 6 7 8 9 10 array (…

Android 面试延伸技术点有哪些,你能答上几个?

1、如何进行单元测试&#xff0c;如何保证 App 稳定 &#xff1f; 参考回答&#xff1a; 要测试 Android 应用程序&#xff0c;通常会创建以下类型自动单元测试 本地测试&#xff1a;只在本地机器 JVM 上运行&#xff0c;以最小化执行时间&#xff0c;这种单元测试不依赖于 An…

JavaScript之ES6高级语法(三)

本文是我在学习过程中记录学习的点点滴滴&#xff0c;目的是为了学完之后巩固一下顺便也和大家分享一下&#xff0c;日后忘记了也可以方便快速的复习。 ES6高级语法(三&#xff09; 前言一、原型对象1.1、constructor 属性1.2、对象原型 二、原型继承三、原型链 前言 今天学习的…

【C++】红黑树的概念与模拟实现

红黑树的概念与模拟实现 红黑树的概念红黑树的性质红黑树节点的定义红黑树的迭代器红黑树的插入红黑树和AVL树的比较红黑树的模拟实现 红黑树的概念 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个结点上增加一个存储位表示结点的颜色&#xff0c;可以是Red或Black。…

计算机组成原理(0)概述

前言 没有想好到底是要怎么学习&#xff0c;看哪个视频课&#xff0c;看到1.2 计算机的基本组成1.2-a1_哔哩哔哩_bilibili 是15年录的视频读PPT课本不一样就更不想看了&#xff0c;但是CSAPP难度大&#xff08;主要是广度&#xff0c;所以可能不很适用于考试或计组的学习&…

java代码审计和安全漏洞修复

java代码审计和安全漏洞修复 本文目录 java代码审计和安全漏洞修复开源&#xff1a;奇安信代码卫士官网使用gitee服务使用 非开源&#xff1a;思客云找八哥错误类型以及修改方法1.硬编码2. 路径操作3. 路径操作 - Zip文件条目覆盖4. SQL注入5. SQL注入 - Hibernate6. XML外部实…