【C++】类和对象之常引用与运算符重载

news2025/2/24 18:23:05

个人主页 : zxctscl
文章封面来自:艺术家–贤海林
如有转载请先通知

文章目录

  • 1. 前言
  • 2. 常引用
  • 3. 运算符重载

1. 前言

在之前的文章中提到了常引用,再来看运算符重载之前,先来看看常引用的使用。

2. 常引用

在使用引用的时候可能会出现一些问题,例如:b是a的别名,b++,那么a肯定也加加了,但有时我们也不希望这样。
在这里插入图片描述
如果不希望a传过去改变,那么就得加上const
在这里插入图片描述
那么这里就能使用const加引用。
在这里插入图片描述
这里用到常引用,c是a的别名,但是不能修改,也就是不能通过c修改a。他是一种权限的缩小 。
在这里插入图片描述

在这里插入图片描述
这里要给x取别名,是不可以的。
因为这里权限放大,这里x是只读的,但y是x别名之后却可读可写,这是不能的。
所以加上const就可以了。
在这里插入图片描述

取别名不能放大权限。
权限缩小是可以的,但是权限放大是不行的。

在这里插入图片描述
像下面这种也是可以的。
z是常量的别名了。
在这里插入图片描述
还可以有这样的。
在这里插入图片描述
但是像下面这样就不行,因为临时变量具有常性,不能被修改。
这里是权限的放大,a+x表达式的返回值是临时对象。
在这里插入图片描述
在这里插入图片描述

如果不用const引用,如果这里传了a,那么后面的10就不能传过去,后面的表达式也不能传过去。
所以建议引用传const。
在这里插入图片描述
得注意:权限可以缩小,权限可以平移,但权限不能放大。
在这里插入图片描述
这里d可以给i,因为隐式类型转换。
但传引用就不行,因为类型不同。
在这里插入图片描述
但是加了const就行,为什么呢?
因为类型转换中间会有临时变量。
在这里插入图片描述
这里严格来说不是把d给i,然后d构造的临时变量拷贝给i。
下面的引用也是一样的,是把d拷贝给临时变量,ri是这个临时变量的别名,因为临时变量具有常性,所以用常引用。
在这里插入图片描述
在这里插入图片描述
那么为什么要产生临时变量呢?
在这里插入图片描述
这里i和ch比较为什么会相等?
因为i和ch不能直接去比较,在操作符两边的操作数类型不一样时,会有类型提升或截断。
这里是不能把ch扩到4个字节,所以这里会产生一个临时变量,ch不会变,变的是ch会产生的有4个字节的临时变量,4个字节把ch的值拿过去以后,按类型提升的规则,最高位也就是符号位,往上补0。a的ascii码值是97,97的最高位是0,往上补,补成4个字节,还是97。所以这里的i不是和ch比较的,而是和那个临时变量比较的。
在这里插入图片描述

3. 运算符重载

C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。

像下面代码,要比较两个日期,不能直接比较。
内置类型就可以,是语言定义的。
自定义类型是多个类型的组合,编译器不知道怎么比较,所以不支持,需要自己来定义。
在这里插入图片描述

class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	//private:
	int _year;
	int _month;
	int _day;
};

bool DateCompare(const Date& x, const Date& y)
{
	return x._year == y._year
		&& x._month == y._month
		&& x._day == y._day;

}

int main()
{
	Date d1(2024, 1, 1);
	Date d2(2024, 2, 27);
	cout << DateCompare(d1, d2) << endl;

在这里插入图片描述
在这里插入图片描述

如果是比较大小,像下面这样是肯定不行的,不是某一个小就小。
在这里插入图片描述
那么该这样写,得先比较年,年小就小,年相同后再是月,月小就小,月再相同才比较天。

bool DateCompare2(const Date& x, const Date& y)
{

	if (x._year < y._year)
	{
		return true;
	}
	else if (x._year == y._year)
	{
		if (x._month < y._month)
		{
			return true;
		}
		else if (x._month == y._month)
		{
			return x._day < y._day;
		}
	}

	return false;
}

在这里插入图片描述

所以自定义类型的比较得实现函数,如果函数名乱取的话,就很难判断它是用来干啥的。
为了避免这样就有了运算符重载。
在这里插入图片描述

函数名字为:关键字operator后面接需要重载的运算符符号
这里的重载是指对运算符的重新定义,按照用户的需求去控制。

函数原型:返回值类型 operator操作符(参数列表)

class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	//private:
	int _year;
	int _month;
	int _day;
};

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


bool operator<(const Date& x, const Date& y)
{
	if (x._year < x._year)
	{
		return true;
	}
	else if (x._year == x._year)
	{
		if (x._month < y._month)
		{
			return true;
		}
		else if (x._month == y._month)
		{
			return x._day < y._day;
		}
	}

	return false;
}

int main()
{
	Date d1(2024, 1, 1);
	Date d2(2024, 2, 27);


	cout << operator==(d1, d2) << endl;
	cout << operator<(d1, d2) << endl;
    
    cout << (operator==(d1, d2)) << endl;

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

在这里插入图片描述
但不仅仅是这样,还有可以直接用
在这里插入图片描述
出现这样的情况是因为<<的优先级比==的高,加上括号就行。
在这里插入图片描述
为什么这里实现结果是一样的呢?
因为编译器会给去调用对应的函数。

在这里插入图片描述
但是在实践中私有变量肯定不是像上面代码一样。在类外面是不能访问的,那怎么办呢?
类外面不能服务,那么就放到类里面。
但不要忘记,类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐藏的this。

class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}

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

	bool operator<(const Date& y)
	{
		if (_year < y._year)
		{
			return true;
		}
		else if (_year == y._year)
		{
			if (_month < y._month)
			{
				return true;
			}
			else if (_month == y._month)
			{
				return _day < y._day;
			}
		}

		return false;
	}

private:
	int _year;
	int _month;
	int _day;
};


int main()
{
	Date d1(2024, 1, 1);
	Date d2(2024, 2, 27);
	cout << d1.operator==(d2) << endl;
	cout << d1.operator<(d2) << endl;

	cout << (d1 == d2) << endl; 
	cout << (d1 < d2) << endl;  

	return 0;
}

在这里插入图片描述
在这里插入图片描述
如果是内置类型去比较,直接转化成指令
在这里插入图片描述

注意:

  1. 不能通过连接其他符号来创建新的操作符:比如operator@
  2. 重载操作符必须有一个类类型参数用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不能改变其含义作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐藏的this。
  3. .* :: sizeof ?: . 注意以上5个运算符不能重载。这个经常在笔试选择题中出现。

有问题请指出,大家一起进步!!!

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

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

相关文章

西门子WINCC客户端提示“未找到启动画面”

WinCC客户端提示“未找到启动画面”&#xff1f; 在WinCC客户机服务器架构中&#xff0c;多用户客户机互连服务器项目时&#xff0c;有时会弹出“未找到启动画面”的提示对话框&#xff0c;并且选择画面后继续弹出该对话框&#xff0c;无法正常显示画面。 可能的原因有&#x…

DevEco Studio下载与安装(Windows)

下载地址&#xff1a; HUAWEI DevEco Studio和SDK下载和升级 | HarmonyOS开发者 安装时直接点击 next 即可。 运⾏已安装的DevEco Studio&#xff0c;⾸次使⽤&#xff0c;请选择Do not import settings&#xff0c;单击OK。 1.安装Node.js 如果本地有下载&#xff0c;可以…

利用观测云实现 Kubernetes 多集群可观测

简介 观测云的工作空间接入多个 Kubernetes 集群时&#xff0c;是如何区分不同集群&#xff0c;达到多集群的可观测性&#xff1f; 增加Tag NAMESPACE&#xff1a;DataKit 选举空间&#xff0c;需要设置 ENV_NAMESPACE 环境变量&#xff0c;值为非空字符&#xff0c;不同集群…

稀疏卷积Sparse Convolution

1. 为什么提出稀疏卷积&#xff1f;它有什么好处&#xff1f; 卷积神经网络已经被证明对于二维图像信号处理是非常有效的。然而&#xff0c;对于三维点云信号&#xff0c;额外的维度显著增加了计算量。 另一方面&#xff0c;与普通图像每个像素都有值不同的是&#xff0c;一般…

从0开始python学习-53.python中flask创建简单接口

目录 1. 创建一个简单的请求,没有写方法时默认为get 2. 创建一个get请求 3. 创建一个post请求&#xff0c;默认可以使用params和表单传参 4. 带有参数的post请求 1. 创建一个简单的请求,没有写方法时默认为get from flask import Flask, request# 初始化一个flask的对象 ap…

细菌,支原体,真菌--细胞培养的最大威胁及解决方法

在科研实验中&#xff0c;微生物污染是细胞培养过程中面临的一项长期的严重威胁。侵入的支原体、细菌、酵母菌和真菌可以直接杀死您宝贵的细胞或者彻底改变培养细胞的特性&#xff0c;导致不准确的实验结果&#xff0c;既耗费时间又浪费资源。InvivoGen/欣博盛生物可以提供多种…

QT Mingw编译ffmpeg源码以及测试

文章目录 前言下载msys2ysamFFmpeg 搭建编译环境安装msys2安装QT Mingw编译器到msys环境中安装ysam测试 编译FFmpeg 前言 FFmpeg不像VLC有支持QT的库文件&#xff0c;它仅提供源码&#xff0c;需要使用者自行编译成对应的库&#xff0c;当使用QTFFmpeg实现播放视频以及视频流时…

Linux系统安装

Linux系统安装 安装包链接 链接&#xff1a;https://pan.baidu.com/s/1FdP7TH90UvKUQuiL2yeGCA 提取码&#xff1a;c49n安装包内容 虚拟机执行文件 详细安装教程 虚拟机密钥 Ubuntu 安装步骤 先点击虚拟机的.EXE文件安装&#xff0c;打开安装教程&#xff0c;有详细的说明。

【Acwing】154滑动窗口

#include<bits/stdc.h> using namespace std;int n,k; int nums[1000010] {0};int main() {ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);cin>>n>>k;// 下面求最小值int cnt 0;int res[1000010] {0};deque<int> q; // 双端队列 for(int i0;i&l…

Zoho Bigin斩获PCMag推崇:小企业首选CRM软件

当我们谈论企业怎样选择CRM管理系统时&#xff0c;大型企业、中型企业以及小型或初创等不同规模的企业需求各不相同&#xff0c;很难用一套软件来适配所有公司。以小企业为例&#xff0c;大多面临预算紧张、没有专业的IT部门或支持团队、暂时用不到高级定制功能等现状。基于这个…

R语言提高效率的技巧(2)

1、R project&#xff1a;加载数据和脚本不需要设置文件夹&#xff1b;打包project文件夹后发给别人&#xff0c;在另外一个环境中&#xff0c;点击.Rproj文件即可运行。 2、下载原始R包&#xff0c;进行补充和修改。 https://cran.r-project.org/web/packages/available_pack…

智能分析网关V4电瓶车检测与烟火算法,全面提升小区消防安全水平

2024年2月23日&#xff0c;南京市某小区因电瓶车停放处起火引发火灾事故&#xff0c;造成巨大人员伤亡和损失。根据国家消防救援局的统计&#xff0c;2023年全国共接报电动自行车火灾2.1万起。电瓶车火灾事故频发&#xff0c;这不得不引起我们的重视和思考&#xff0c;尤其是在…

RK3568 android11 调试陀螺仪模块 MPU6500

一&#xff0c;MPU6500功能介绍 1.简介 MPU6500是一款由TDK生产的运动/惯性传感器&#xff0c;属于惯性测量设备&#xff08;IMU&#xff09;的一种。MPU6500集成了3轴加速度计、3轴陀螺仪和一个板载数字运动处理器&#xff08;DMP&#xff09;&#xff0c;能够提供6轴的运动…

Socket网络编程(三)——TCP快速入门

目录 概述TCP连接可靠性1. 三次握手过程2. 四次挥手过程3. 为什么挥手需要四次&#xff1f; 传输可靠性TCP核心APITCP传输初始化配置&建立连接客户端创建Socket建立连接服务端创建ServerSocket监听连接ServerSocket 和 Socket的关系 Socket基本数据类型传输客户端数据传输服…

【MySQL】内置函数 -- 详解

一、日期函数 日期&#xff1a;年月日时间&#xff1a;时分秒 1、获得年月日 2、获得时分秒 3、获得时间戳 4、在日期的基础上加日期 5、在日期的基础上减去时间 6、计算两个日期之间相差多少天 7、获得当前时间 ⚪练习 &#xff08;1&#xff09;记录生日 &#xff08;2&…

反转局部链表+牛客

题目链接 链表内指定区间反转_牛客题霸_牛客网 题目描述 代码实现 class Solution { public:/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值即可** * param head ListNode类 * param m int整型 * param n int整型 * retur…

微服务篇之分布式事务

一、Seata架构 Seata事务管理中有三个重要的角色&#xff1a; TC (Transaction Coordinator) - 事务协调者&#xff1a;维护全局和分支事务的状态&#xff0c;协调全局事务提交或回滚。 TM (Transaction Manager) - 事务管理器&#xff1a;定义全局事务的范围、开始全局事务、…

ConvTranspose1d详解

文章目录 ConvTranspose1d简介二、Parameters三、Shape1、Input(batch_size, in_channels, input_length)2、kernel_size(in_channels, out_channels, kernel_size)3、Output(batch_size, out_channels, output_length) 四、Variables ConvTranspose1d简介 class torch.nn.Con…

c++ for 循环语句

循环语句 在C中&#xff0c;有几种循环语句可用于重复执行一段代码&#xff0c;直到满足指定条件为止&#xff0c;主要有 for 循环、while 循环、do-while 循环三种循环语句。三者区别&#xff1a; 循环类型特点for 循环1. 适用于已知循环次数的情况&#xff0c;循环次数事先…

threejs 大场景下,对小模型进行贴图处理

接上篇小模型的删除☞threeJS 大模型中对小模型进行删除-CSDN博客 针对已有模型&#xff0c;根据数据状态进行贴图处理&#xff0c;例如&#xff1a;机房内电脑告警状态、电脑开关机状态下的不同状态贴图等 示例模型还是以丛林小屋为例&#xff1a;针对该模型中的树干进行贴图…