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

个人主页 : 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.hqwc.cn/news/496828.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TCP/IP-常用网络协议自定义结构体

1、TCP/IP模型&#xff1a; 2、TCP/IP- 各层级网络协议&#xff08;从下往上&#xff09;&#xff1a; 1&#xff09;数据链路层&#xff1a; ARP: 地址解析协议&#xff0c;用IP地址获取MAC地址的协议&#xff0c;通过ip的地址获取mac地 …

POST参数里加号+变成空格的问题处理

今天遇到个这样的问题&#xff0c;从前端传到后端的加密报文&#xff0c;里面包含了号&#xff0c;但在后端日志输出看出&#xff0c;变成空格。这个是由于经过RSA加密后引起的 解决办法&#xff1a; 1.前端转码&#xff1a;使用encodeURIComponent对参数进行转码 2.后端解码…

深入理解Lucene:开源全文搜索引擎的核心技术解析

欢迎关注微信公众号&#xff1a;一休哥助手。多种功能等待你的使用。1. 介绍 Lucene是什么&#xff1f; Lucene是一个开源的全文搜索引擎库&#xff0c;提供了强大的文本搜索和检索功能。它由Apache软件基金会维护和开发&#xff0c;采用Java语言编写&#xff0c;因其高性能、…

Docker(运维工具)—— 学习笔记

快速构建、运行、管理应用的工具 一、安装docker 参考Install Docker Engine on Ubuntu | Docker Docs 二、快速入门 1、镜像和容器 docker镜像可以做到忽略操作系统的差异&#xff0c;跨平台运行&#xff0c;忽略安装的差异 当我们利用Docker安装应用时&#xff0c;Dock…

如何使用Fastapi上传文件?先从请求体数据讲起

文章目录 1、请求体数据2、form表单数据3、小文件上传1.单文件上传2.多文件上传 4、大文件上传1.单文件上传2.多文件上传 1、请求体数据 前面我们讲到&#xff0c;get请求中&#xff0c;我们将请求数据放在url中&#xff0c;其实是非常不安全的&#xff0c;我们更愿意将请求数…

QML | JavaScript函数[自定义方法\导入JavaScript文件中的函数\关联信号和JavaScript 函数]

1、JavaScript函数 在前面的方法特性一节中已经讲解了函数的使用,这里再从JavaScript的角度讲解一些需要注意的方面。程序逻辑可以在JavaScript函数中进行定义。这些函数可以定义在QML文档里面(例如前面讲到的自定义方法),也可以定义在外部导人的JavaScript文件中。 (1)自…

拒绝机械风,让ChatGPT像真人一样对话!

拒绝机械风&#xff0c;让ChatGPT像真人一样对话 在这个信息爆炸的时代&#xff0c;人工智能技术的快速发展让我们的生活变得更加便捷。 特别是在自然语言处理领域&#xff0c;ChatGPT的出现无疑是一次革命性的进步。 然而&#xff0c;虽然ChatGPT在很多方面表现出了惊人的能…

学习笔记-李沐动手学深度学习(七)(19-21,卷积层、填充padding、步幅stride、多输入多输出通道)

总结 19-卷积层 【补充】看评论区建议的卷积动画视频 数学中的卷积 【链接】https://www.bilibili.com/video/BV1VV411478E/?fromsearch&seid1725700777641154181&vd_sourcee81e116c4ffe5e79d4bc44738263eda4 【可判断是否为卷积的典型标志】两个函数中自变量相加…

【HarmonyOS】鸿蒙开发之Video组件——第3.7章

Video组件内VideoOptions属性简介 src&#xff1a;设置视频地址。currentProgressRate&#xff1a;设置视频播放倍速&#xff0c;参数说明如下&#xff1a; number|string&#xff1a;只支持 0.75 &#xff0c; 1.0 &#xff0c; 1.25 &#xff0c; 1.75 &#xff0c; 2.0 。P…

vue-router4 (六) 命名视图

命名视图可以使得同一级&#xff08;同一个组件&#xff09;中展示更多的路由视图&#xff0c;而不是嵌套显示&#xff0c; 命名视图可以让一个组件中具有多个路由渲染出口&#xff0c;这对于一些特定的布局组件非常有用。 应用场景&#xff1a; 比如点击login切换到组件A&am…

安装 docker 可视化工具 portainer

portainer 官方网站 https://www.portainer.io/ 一、portainer 介绍 Portainer是一款开源的容器管理平台&#xff0c;它提供了一个直观易用的Web界面&#xff0c;帮助用户管理Docker容器集群、镜像、卷等资源。Portainer 支持多种 Docker 环境&#xff0c;包括本地Docker、Sw…

数据库之MVCC

1、什么是MVCC MVCC&#xff08;Multi-Version Concurrency Control&#xff09;即多版本并发控制。MVCC 是一种并发控制的方法&#xff0c;一般在数据库管理系统中&#xff0c;实现对数据库的并发访问。MVCC使得大部分支持行锁的事务引擎&#xff0c;不再单纯的使用行锁来进行…