【C++】运算符重载 | 赋值运算符重载
Ⅰ. 运算符重载
引入
❓什么叫运算符重载?
就是:运用函数,将现有的运算符重新定义,使其能满足各种自定义类型的运算。
回想一下,我们以前运算的对象是不是都是int、char这种内置类型?
那我们自定义的“preson”类型,想要进行加减运算,该怎么办呢?
这就需要运算符重载。
概念
运算符重载是具有特殊函数名的函数,
也具有其返回值类型、函数名及参数列表。
函数名:关键字operator后面接需要重载的运算符符号。
格式:返回值类型 operator 操作符(参数列表)
1.常用的操作符有:+、-、*、/、++、--、=(赋值)、==(判断相等)、>、<、>=、<=等
2.有几个操作数,就有几个形参。
不过,当重载成员函数时,有一个形参是隐形的,即this指针。
✨说明:
1.不能通过连接其他符号来创建新的操作符。
如:operator@
2.重载操作符必须有一个类类型的参数。
如果参数里没有类类型,那运算符重载还有啥意义。
3.用于内置类型的运算符,其含义不能改变。
如:内置的 整型 +,不能改变其含义
4.作为类成员函数重载时,其形参看起来比操作数少1,
因为成员函数的第一个参数为隐藏的this。
(见下面的例子)
5.(笔试选择题常考)这5个运算符不能重载:
.* 点星运算符
: : 域运算符
sizeof
? : 条件运算符
. 点运算符
6.运算符重载写好了以后,直接用就行。编译器会自动调用函数。
Date& operator+=(int day){
…
}
d1+=100; //直接用。调用会自动完成🤣
举例
class Date
{
public:Date(int year = 2000, int month = 1, int day = 1){_year = year;_month = month;_day = day;} //需要注意的是,左操作数是this,指向调用函数的对象bool operator==(const Date& d) //bool operator==(Date*this,const Date& d){return _year == d._year && //其实是this->_year==d._year_month == d._month &&_day == d._day;}
private:int _year;int _month;int _day;
};
int main()
{Date d1(2023, 8, 12);Date d2(2023, 8, 12);cout << (d2 == d1) << endl;
}
结果为:

Ⅱ. 赋值运算符重载
概念
赋值运算符重载作为类的6大成员函数之一,
负责将一个对象赋值给另一个对象。
如果我们不写,那编译器会自动生成。
格式
T& operator =(const T& 参数)

✨说明:
1.参数类型为const T&。传引用可以提高传参效率。
2.返回类型为T&。
❓你可能会疑惑:这里只要完成赋值动作的话,返回类型为void不就可以了吗?
为什么要有返回值呢?
有返回值其实是为了支持连续赋值。
如”d1=d2=d3;“ 要想连续赋值,
那d2=d3在调用完函数以后要有一个返回值,这个返回值作为右操作数,参与到d1=…中去。
如果返回void,那d1=空,无法完成连续赋值。
所以,要想连续赋值,就得有返回值。
在返回时,我们尽量使用引用返回。
因为能减少传参过程中的拷贝,效率更高。
不信我们来实验下,
通过对比 传值返回与传引用 调用拷贝构造函数 的次数,
来看 传引用究竟有没有减少拷贝!
实验组1:传值
class Date
{
public:Date(int year = 2000, int month = 1, int day = 1){_year = year;_month = month;_day = day;}Date(const Date& d) //我们自己写一个拷贝构造函数{ //这样,它每次被调用,都会打印出来cout << "我被调用了!" << endl;_year = d._year;_month = d._month;_day = d._day;}Date operator=(const Date& d) //传值是可以的,但是没有引用好{ //实验结果将为我们证明这一点_year = d._year;_month = d._month;_day = d._day;return *this;}
private:int _year;int _month;int _day;
};
int main()
{Date d1(2023, 8, 12);Date d2(2023, 8, 12);Date d3(2000, 1, 1);Date d4(2020, 1, 1);d1 = d2 =d3 = d4;
}
结果为:(这已经是被优化后的结果)
实验组2:传引用
...Date& operator=(const Date& d) //传引用{_year = d._year;_month = d._month;_day = d._day;return *this;}...
结果为:
实验证明,传引用比传值调用拷贝构造函数的次数少,效率更高。
所以,我们能传引用的地方,就尽量传引用。
3.检测是否自己给自己赋值。
如果是”d1=d1;“那这样的赋值完全没意义。
为了更高效,我们用if语句来避免自己给自己赋值的情况。
Date& operator=(const Date& d){if (this != &d) //加上判断{_year = d._year;_month = d._month;_day = d._day;return *this;}}
注:我们要用this去判断,不要用对象!
因为对象仅能判断值是否相等,而this能从地址判断它俩是否是同一个。
4.返回*this。
为什么可以返回*this?
我们知道,函数的局部变量是不能返回的,
因为局部变量在出了作用域就销毁了。
而这里不同,*this是 作用域在函数外面的 对象。
出作用域,对象并不会因此销毁。所以*this有效。
只能重载成成员函数
赋值运算符只能重载成成员函数,不能重载成全局函数。😥
因为如果不在类中实现,那编译器会生成一个默认的。
此时你在类外实现的全局运算符重载,就和默认的那个冲突了。
因此,赋值运算符必须定义成成员函数。
赋值or拷贝构造?
来看这个例子:这两种写法,分别是赋值还是拷贝构造?
其实都是拷贝构造!
赋值操作的是一个已存在的变量👌,而拷贝构造是定义一个新的变量。
默认赋值运算符重载
当你没有显示实现时,编译器会自动生成一个默认的赋值运算符重载,
以值的方式逐字节拷贝。
注:内置类型成员是直接赋值的,
而自定义类型成员变量需要调用 对应类的 赋值运算符重载 来完成赋值。
我们演示一下:
class Date {
public:Date(int year = 2000, int month = 1, int day = 1){this->_year = year;this->_month = month;this->_day = day;}
private:int _year;int _month;int _day;
};
int main(void)
{Date d1(2010,1,1);Date d2(2023,8,12);//我们并未实现,d1 = d2; //但这里会自动调用 默认赋值运算符重载return 0;
}
结果:

❓既然默认生成的已经可以完成值的拷贝了,那还需要我们自己去实现吗?
如果是像日期类这种,是不需要的,值拷贝已经足够。
但如果涉及资源管理,
如动态内存分配、指针、打开的文件等,就得深拷贝,
这时就必须要自己去实现了。
(这里的原因和拷贝构造函数那儿是贯通的。)
原因再说明一下:
如果有指针,而默认的赋值运算符重载只能浅拷贝,
并不会再开一块指针指向的空间。
这就导致了两个指针指向同一块空间,彼此相互影响。

相关文章:
【C++】运算符重载 | 赋值运算符重载
Ⅰ. 运算符重载 引入 ❓什么叫运算符重载? 就是:运用函数,将现有的运算符重新定义,使其能满足各种自定义类型的运算。 回想一下,我们以前运算的对象是不是都是int、char这种内置类型? 那我们自定义的“…...
Python学习 -- 类对象从创建到常用函数
在Python编程中,类是一种强大的工具,用于创建具有共同属性和行为的对象。本篇博客将详细介绍Python中类和对象的创建,类的属性和方法,以及一些常用的类函数,通过丰富的代码例子来帮助读者深入理解。 一、类和对象的创…...
数组分割(2023省蓝桥杯)n种讨论 JAVA
目录 1、题目描述:2、前言:3、动态规划(bug):3、递归 剪枝(超时):4、数学(正解): 1、题目描述: 小蓝有一个长度为 N 的数组 A [A0, A1,…, AN−…...
很好的启用window10专业版系统自带的远程桌面
启用window10专业版系统自带的远程桌面 文章目录 启用window10专业版系统自带的远程桌面前言1.找到远程桌面的开关2. 找到“应用”项目3. 打开需要远程操作的电脑远程桌面功能 总结 前言 Windows操作系统作为应用最广泛的个人电脑操作系统,在我们身边几乎随处可见。…...
TCP定制协议,序列化和反序列化
目录 前言 1.理解协议 2.网络版本计算器 2.1设计思路 2.2接口设计 2.3代码实现: 2.4编译测试 总结 前言 在之前的文章中,我们说TCP是面向字节流的,但是可能对于面向字节流这个概念,其实并不理解的,今天我们要介…...
YOLOX在启智AI GPU/CPU平台部署笔记
文章目录 1. 概述2. 部署2.1 拉取YOLOX源码2.2 拉取模型文件yolox_s.pth2.3 安装依赖包2.4 安装yolox2.5 测试运行2.6 运行报错处理2.6.1 ImportError: libGL.so.1: cannot open shared object file: No such file or directory2.6.2 ImportError: libgthread-2.0.so.0: cannot…...
23种设计模式攻关
👍一、创建者模式 🔖1.1、单例模式 单例模式(Singleton Pattern),用于确保一个类只有一个实例,并提供全局访问点。 在某些情况下,我们需要确保一个类只能有一个实例,比如数据库连接…...
【jsthreeJS】入门three,并实现3D汽车展示厅,附带全码
首先放个最终效果图: 三维(3D)概念: 三维(3D)是一个描述物体在三个空间坐标轴上的位置和形态的概念。相比于二维(2D)只有长度和宽度的平面,三维增加了高度或深度这一维度…...
unity将结构体/列表与json字符串相互转化
编写Unity程序时,面对大量需要传输或者保存的数据时,为了避免编写重复的代码,故采用NewtonJson插件来将定义好的结构体以及列表等转为json字符串来进行保存和传输。 具体代码如下: using System; using System.IO; using Newtons…...
【Vue】vue2项目使用swiper轮播图2023年8月21日实战保姆级教程
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、npm 下载swiper二、使用步骤1.引入库声明变量2.编写页面3.执行js 总结 前言 swiper轮播图官网 参考文章,最好先看完他的介绍,再看…...
【算法日志】贪心算法刷题:单调递增数列,贪心算法总结(day32)
代码随想录刷题60Day 目录 前言 单调递增数列 贪心算法总结 前言 今天是贪心算法刷题的最后一天,今天本来是打算刷两道题,其中的一道hard题做了好久都没有做出来(主要思路错了)。然后再总结一下。 单调递增数列 int monotoneIncreasingDigits(int n…...
MATLAB算法实战应用案例精讲-【深度学习】模型压缩
目录 模型压缩概述 1. 为什么需要模型压缩 2. 模型压缩的基本方法 Patient-KD 1. Patient-KD 简介...
Matlab使用
Matlab使用 界面介绍 新建脚本:实际上就是新建一个新建后缀为.m的文件 新建编辑器:ctrlN 打开:打开最近文件,以找到最近写过的文件 点击路径,切换当前文件夹 预设:定制习惯用的界面 常见简单指令 ;…...
BladeX多数据源配置
启用多租户数据库隔离,会默认关闭mybatis-plus多数据源插件的启动,从而使用自定义的数据源识别 若不需要租户数据库隔离只需要字段隔离,而又需要用到多数据源的情况,需要前往LauncherService单独配置 数据源切换失败 详情请看说明…...
go里面关于超时的设计
设想一下你在接收源源不断的数据,如果有700ms没有收到,则认为是一个超时,需要做出处理。 逻辑上可以设计一个grouting,里面放一个通道,每收到一条数据进行相应处理。通道中夹杂一个timer定时器的处理,若通道在700ms内…...
Qt下使用ModbusTcp通信协议进行PLC线圈/保持寄存器的读写(32位有符号数)
文章目录 前言一、引入Modbus模块二、Modbus设备的连接三、各寄存器数据的读取四、各寄存器数据的写入五、示例完整代码总结 前言 本文主要讲述了使用Qt的Modbus模块来进行ModbusTcp的通信,实现对PLC的线圈寄存器和保持寄存器的读写,基于TCP/IP的Modbus…...
ElasticSearch学习2
1、索引的操作 1、创建索引 对ES的操作其实就是发送一个restful请求,kibana中在DevTools中进行ES操作 创建索引时需要注意ES的版本,不同版本的ES创建索引的语句略有差别,会导致失败 如下创建一个名为people的索引,settings&…...
3D角色展示
先看效果: 再看代码: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>3D卡片悬停</title><style>font-face {font-family: "Exoct";src: url("htt…...
前端面试:【Angular】打造强大Web应用的全栈框架
嗨,亲爱的Angular探险家!在前端开发的旅程中,有一个全栈框架,那就是Angular。Angular提供了模块化、组件化、依赖注入、路由和RxJS等特性,助力你构建强大、可扩展的Web应用。 1. 什么是Angular? Angular是…...
数据结构:栈和队列
文章目录 一、栈1.栈的概念及结构1.栈的概念及结构2.栈的实现 2.栈的顺序表实现1.栈的结构体和实现的功能函数2.栈的初始化,入栈和出栈操作3.栈的其他操作 3.栈的链表实现1.栈的结构体和实现的功能函数2.栈功能函数的实现 二、队列1.队列的概念及结构1.队列的概念及…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...
SQL Server 触发器调用存储过程实现发送 HTTP 请求
文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...
【实施指南】Android客户端HTTPS双向认证实施指南
🔐 一、所需准备材料 证书文件(6类核心文件) 类型 格式 作用 Android端要求 CA根证书 .crt/.pem 验证服务器/客户端证书合法性 需预置到Android信任库 服务器证书 .crt 服务器身份证明 客户端需持有以验证服务器 客户端证书 .crt 客户端身份…...
客户案例 | 短视频点播企业海外视频加速与成本优化:MediaPackage+Cloudfront 技术重构实践
01技术背景与业务挑战 某短视频点播企业深耕国内用户市场,但其后台应用系统部署于东南亚印尼 IDC 机房。 随着业务规模扩大,传统架构已较难满足当前企业发展的需求,企业面临着三重挑战: ① 业务:国内用户访问海外服…...
Python环境安装与虚拟环境配置详解
本文档旨在为Python开发者提供一站式的环境安装与虚拟环境配置指南,适用于Windows、macOS和Linux系统。无论你是初学者还是有经验的开发者,都能在此找到适合自己的环境搭建方法和常见问题的解决方案。 快速开始 一分钟快速安装与虚拟环境配置 # macOS/…...
