c++ 运算符重载

为什么要有运算符重载?

观察下列代码,当我们要比较两个日期类(自定义类型)的大小的时候,我们没法使用编译器自带的小于<符号来比较,就像这样的形式:d1 < d2
我们需要自己写一个函数来进行比较,这是很麻烦的。我们想要编译器来帮我们比较,而不需要自己去写一个函数。这个时候就要用到运算符重载。

//需要自己写一个函数来比较。
bool DateLess(const Date& x1, const Date& x2)
{
	if (x1._year < x2._year)
		return true;
	else if (x1._year == x2._year && x1._month < x2._month)
		return true;
	else if (x1._year == x2._year && x1._month == x2._month && x1._day < x2._day)
		return true;
	else
		return false;
}
int main()
{

	Date d1(2023, 7, 23);
	Date d2(2023, 8, 21);
    //比较两个日期类的大小
	cout << DateLess(d1, d2) << endl;



	return 0;
}

如何操作呢?

使用operator< 来命名函数,(operator< :是一个特殊的成员函数相当于对 运算方式的重新定义)这样一来,在使用的时候就可以使用
< 符号了。
在这里插入图片描述

注意事项:

c++引入运算符重载是为了增强代码的可读性才引入的
运算符重载是具有特殊函数名的函数,也具有其相应的返回值类型,函数名字以及参数列表,其返回值的类型与参数列表和普通的函数类似。
函数的名字为:operator+需要重载的运算符号
函数原型:返回值类型 opera操作符(参数列表)
注意:

  1. operator后面的操作符必须是以前就有实际意义的操作符(就像,+,,/。)不能跟其他一些无意义的操作符号比如:'@'符号。
  2. 运算符重载至少有一个参数必须是自定义类型。
  3. 运算符重载不能改变操作符的操作数的个数,打个比方:
    小于号 '<' 有两个操作数,左边一个,右边一个。比如:a < b, 你不能把它改变成三个操作数:ab<c
    ++只有一个操作数。比如i++你不能把它改变成两个操作数:i++j
    一个操作符是几个操作数,那么重载之后他也就该有几个操作数不会增加,也不会减少。
  4. 下面这几个运算符是不能重载的:
    (1)域作用限定符不能重载: ::
    (2)sizeof不能重载
    (3)三目运算符不能重载: ? :
    (4)点不能重载: . (对象变量之类的,取他的成员就用了点操作符)
    (5)点星不能重载: .* (这里的点星是连在一起的,是一个整体。)
    (6)星是可以重载的,*

有坑未填

上面那个operator函数的实际场景我并未写出来,下面,我把所有代码拿出来看看:

#include<iostream>
using namespace std;

//日期类
class Date
{
public:
	//默认构造
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}


	//拷贝构造函数 用同类型的对象来初拷贝始化它,所以叫拷贝构造
	Date(Date& d)
	{
		cout << "Date(Date& d)" << endl;
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}



	void Print()
	{
		cout << _year << "/" << _month << "/" << _day << endl;
	}



//没填的坑就在这里,注意看!!!!!!!!!!!!!!!!!!!!
//没填的坑就在这里,注意看!!!!!!!!!!!!!!!!!!!!
//没填的坑就在这里,注意看!!!!!!!!!!!!!!!!!!!!
//没填的坑就在这里,注意看!!!!!!!!!!!!!!!!!!!!
//private:       //这里把private注释掉了
	int _year;
	int _month;
	int _day;

};

//这个就是我们写的那个重载运算符的函数
bool operator<(const Date& x1, const Date& x2)
{
	if (x1._year < x2._year)
		return true;
	else if (x1._year == x2._year && x1._month < x2._month)
		return true;
	else if (x1._year == x2._year && x1._month == x2._month && x1._day < x2._day)
		return true;
	else
		return false;
}





int main()
{

	Date d1(2023, 7, 23);
	Date d2(2023, 8, 21);

	 cout << (d1 < d2) << endl;
	return 0;
}

首先我们来解释我们为什么要把private注释掉?
我们知道private是限制访问的。它里面修饰的是成员变量。成员变量是不允许外界访问的。
可是当我们调用运算符重载的那个operator<函数的时候,我们需要给这个函数传参吧?
但是我们给这个函数传的参数是类里面的成员变量。
所以说这个时候我们要访问成员变量。但是private阻止了我们,不许我们访问。所以说我们把它注释掉了。
但是这始终不是个办法呀。我们还是希望private能继续发挥他的作用。因为private能阻止其他的一些非法访问。
所以我们现在的需求变成了这样:
我们希望private能继续发挥它的功能,同时我们也希望operator<函数能继续访问成员变量。
那怎么办?
我们知道成员函数是可以访问成员变量的。
所以我们只需要把operator<变成成员函数就行了,即:把它放在里面。
但是这个时候又会出现一个问题。当你运行的时候,编译器会报错,说你的operator<操作数太多了。
在这里插入图片描述
在这里插入图片描述

但是你一看,诶,你就只有两个操作数呀?没有变多呀。这是怎么回事?
你难道忘了在面有一个隐藏的参数:this指针
所以啊就变成了三个操作数了。
所以这个时候你要删掉一个操作数就行了

这样就行了:

 // 这个时候这个函数看似只有一个参数,实则有两个参数
 //因为还有一个隐藏的this 指针
	bool 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 == _month && _day < d._day)
			return true;
		else
			return false;
	}

在这里插入图片描述
这个时候当编译器看到上面的这串代码,实际上是这样的
d1 < d2
会被转化为
d1 . operator<(d2)
这个时候this指针 是指向d1

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

YOLOv5源码中的参数超详细解析(2)— 配置文件yolov5s.yaml

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。YOLOv5配置了5种不同大小的网络模型&#xff0c;分别是YOLOv5n、YOLOv5s、YOLOv5m、YOLOv5l、YOLOv5x&#xff0c;其中YOLOv5n是网络深度和宽度最小但检测速度最快的模型&#xff0c;其他4种模型都是在YOLOv5n的基础上不断…

深度补全算法-CompletionFormer-已开源效果最好

《CompletionFormer: Depth Completion with Convolutions and Vision Transformers 》 摘要 给定稀疏深度和相应的 RGB 图像&#xff0c;深度补全旨在整个图像中空间传播稀疏测量值&#xff0c;以获得密集的深度预测。尽管基于深度学习的深度补全方法取得了巨大进步&#xff0…

分清性能测试,负载测试,压力测试这三个的区别

做测试一年多来&#xff0c;虽然平时的工作都能很好的完成&#xff0c;但最近突然发现自己在关于测试的整体知识体系上面的了解很是欠缺&#xff0c;所以&#xff0c;在工作之余也做了一些测试方面的知识的补充。不足之处&#xff0c;还请大家多多交流&#xff0c;互相学习。 …

从 GPT4All 体验 LLM

推荐&#xff1a;使用 NSDT场景编辑器 助你快速搭建可编辑的3D应用场景 什么是 GPT4All&#xff1f; 术语“GPT”源自 Radford 等人 2018 年论文的标题“通过生成预训练提高语言理解”。本文描述了如何证明变压器模型能够理解人类语言。 从那时起&#xff0c;许多人尝试使用转…

UNIX 入门

与 UNIX 建立连接启动会话登录命令提示符修改口令退出系统 简单的 UNIX 命令命令格式ls 命令who 命令虚拟终端 tty伪终端 ptywho am i 命令 cal 命令help 命令man 命令 shell 概述shell 命令更换 shell临时更改 shell永久更改 shell 登录过程 与 UNIX 建立连接 启动会话 要启…

爬虫010_列表高级_添加_append_extend_修改_查询_in_not int_删除_del_pop_remove---python工作笔记029

然后再来看列表操作 首先添加append方法 然后插入,坐标是要插入的下标,右边是插入的内容 看结果 1,2,3,4,5,6 然后这个extend,是逐个插入,放到后边 然后是修改,直接对下标赋值 看结果</

Matlab之利用MarkerFaceColor来填充marker

matlab画图在加一些marker的时候, 有实心的圆圈, 比如: plot(x,y,.r,MarkerSize,20)但是如果想要一个很大的marker, 就需要把这个markersize调得很大, 比如MarkerSize20 但是也可以用空心的圆圈然后把中间涂上颜色, 这样调整起来更方便. 比如: plot(x,y,or,MarkerSize,5,Mar…

【LeetCode每日一题】——219.存在重复元素II

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时间频度】九【代码实现】十【提交结果】 一【题目类别】 哈希表 二【题目难度】 简单 三【题目编号】 219.存在重复元素II 四【题目描述】 给你一个…

MySQL多实例下安装不同的版本

MySQL多版本安装 主要步骤&#xff1a; 1. 在/etc/my.cnf 配置中&#xff0c;更改对应配置。相对于同一版本多实例需要配置的参数&#xff0c;不同版本多实例需要多配置basedir参数&#xff0c;指向mysql的解压目录。 2. 初始化数据目录。进入对应解压的MySQL目录&#xff…

如何使用Kafka构建事件驱动的架构

事件驱动的架构(EDA)是一种软件设计模式&#xff0c;它关注事件的生成、检测和使用&#xff0c;以支持高效和可扩展的系统。在EDA中&#xff0c;事件是组件之间通信的主要手段&#xff0c;允许它们实时交互和响应更改。这种架构促进了松散耦合、可扩展性和响应性&#xff0c;使…

【JAVA】有关时间的操作在编程中如何实现?

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️初识JAVA】 文章目录 前言Date 类Date 类方法Data的缺陷实例获取当前日期时间日期比较java中设置date数据的显示格式 前言 在许多应用程序中&#xff0c;日期和时间的处理是必不可少的。Java提供了一…

C语言数组第十课---------------三子棋-------数组经典练手题

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; &#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382;…

【数据结构】带你图文结合深入栈和队列,并具体分步实现

君兮_的个人主页 勤时当勉励 岁月不待人 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;我们继续来学习初阶数据结构的内容&#xff0c;今天我们要讲的是栈与队列部分的内容&#xff0c;这篇博客先讲栈&#xff0c;队列我们放到下次再讲 好了&#xff0c;废…

PY32F003 FLASH

了解py32芯片的flash内容&#xff0c;对于py32进行api升级有更好的了解的操作 //uiOffset 0(4MHz), 1(8MHz), 2(16MHz), 3(22.12MHz), 4(24MHz) void SetFlashParameter(uint32_t uiOffset) {WRITE_REG(FLASH->KEYR, FLASH_KEY1);WRITE_REG(FLASH->KEYR, FLASH_KEY2); …

解决Error running XXXApplicationCommand line is too long.报错

测试IDEA版本&#xff1a;2019.2.4 &#xff0c;2020.1.3 文章目录 一. 问题场景二. 报错原因2.1 为什么命令行过长会导致这种问题? 三. 解决方案3.1 方案一3.2 方案二 一. 问题场景 当我们从GitHub或公司自己搭建的git仓库上拉取项目代码时&#xff0c;会出现以下错误 报错代…

PHP8的循环控制语句-PHP8知识详解

我们在上一节讲的是条件控制语句&#xff0c;本节课程我们讲解循环控制语句。循环控制语句中&#xff0c;主要有for循环、while循环、do...while循环和foreach循环。 在编写代码时&#xff0c;经常需要反复运行同一代码块。我们可以使用循环来执行这样的任务&#xff0c;而不是…

GWJDN-400型2MHZ自动平衡高温介电温谱仪

GWJDN-400型2MHZ自动平衡高温介电温谱仪 GWJDN-400型2MHZ自动平衡高温介电温谱仪 关键词&#xff1a;介电常数&#xff0c;高温介电&#xff0c;自动平衡 主要功能&#xff1a; 材料介电常数测试仪 半导体材料的介电常数、导电率和C-V特性液晶材料:液晶单元的介电常数、弹性…

新能源汽车交流充电桩控制主板的功能维度

新能源汽车交流充电桩控制主板的功能维度 交流充电桩主板是电动汽车充电站的关键组件&#xff0c;它负责控制充电过程&#xff0c;保护设备和电网免受电动汽车充电的冲击。它具有控制、保护、检测、报警和记录等功能&#xff0c;可以有效地控制充电过程&#xff0c;保证交流充电…

dueling network原理和实现

算法原理&#xff1a; Q ( s , a ; θ , α , β ) V ( s ; θ , β ) ( A ( s , a ; θ , α ) − max ⁡ a ′ ∈ ∣ A ∣ A ( s , a ′ ; θ , α ) ) . \begin{gathered}Q(s,a;\theta,\alpha,\beta)V(s;\theta,\beta)\left(A(s,a;\theta,\alpha)-\max_{a\in|\mathcal{A}…

文件或目录损坏且无法读取

如上图报错&#xff0c;我们直接用cmd命令输入【CHKDSK C: /F】然后回车 电脑重启后可以了&#xff0c;希望能帮助各位小伙伴