【C++】运算符重载详解

💗个人主页💗
⭐个人专栏——C++学习⭐
💫点击关注🤩一起学习C语言💯💫

目录

导读

1. 为什么需要运算符重载

2. 运算符重载概念

3. 运算符重载示例

3.1 == 运算符重载

3.2 >或<运算符

4. 运算符重载参数

5. 全局运算符重载函数

6. 赋值运算符重载

6.1 语法及概念

6.2 示例

6.3 为何使用引用


导读

前面我们学习了默认成员函数:构造函数、析构函数和拷贝构造函数。

今天我们来学习赋值运算符重载。

1. 为什么需要运算符重载

我们一般的运算符只能对于数字进行运算,或是比较大小,但是如果我们想要对我们所定义的自定义类型进行运算呢?

为了使自定义类型能够支持运算符操作,可以通过运算符重载的方式来重新定义这些运算符,使其能够在自定义类型上执行特定的操作。

比如我们定义了一个日期类,想要对这个日期类进行加减运算,亦或是比较两个日期的大小,通过运算符重载即可实现。

2. 运算符重载概念

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

函数名字为:关键字operator后面接需要重载的运算符符号。

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

一般来说需要遵循以下几个原则:

  1. 运算符的重载必须定义在类、结构体或枚举中。

  2. 运算符重载函数必须使用特殊的命名约定,以指示要重载的运算符。

  3. 运算符重载函数可以是类的成员函数,也可以是非成员函数。

  4. 运算符重载函数的参数和返回值类型应该与运算符原有的操作数类型相匹配。

  5. 运算符重载函数可以使用其他的运算符或已有的函数来实现其操作。

3. 运算符重载示例

3.1 == 运算符重载

我们来判断两个日期是否相等:

我们需要依次比较年、月、日。

class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}//operator运算符 做函数名bool operator == (const Date& y){return _year == y._year&& _month == y._month&& _day == y._day;}private:int _year;int _month;int _day;
};int main()
{Date d1(2024, 2, 02);Date d2(2024, 2, 03);cout << d1.operator ==  (d2) << endl;return 0;
}

我们知道,运算符重载也是默认成员函数之一,也就是我们不去调用,编译器也会自动帮我们调用。

比如:

class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}//operator运算符 做函数名bool operator == (const Date& y){return _year == y._year&& _month == y._month&& _day == y._day;}private:int _year;int _month;int _day;
};int main()
{Date d1(2024, 2, 3);Date d2(2024, 2, 2);cout << d1.operator ==  (d2) << endl;cout << (d1 == d2) << endl;return 0;
}

3.2 >或<运算符

判断两个日期的大小:

class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}//operator运算符 做函数名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, 28);Date d2(2024, 1, 29);cout << d1.operator < (d2) << endl;cout << (d1 < d2) << endl;return 0;
}

4. 运算符重载参数

上述我们的代码明明是对两个日期进行比较,为何只有一个参数呢?

运算符重载函数的参数取决于要重载的运算符的操作数个数和类型。

  1. 一元运算符重载:一元运算符只有一个操作数。在重载一元运算符时,通常将其定义为类的成员函数,没有参数(除了隐式的this指针)。

  2. 二元运算符重载:二元运算符有两个操作数。在重载二元运算符时,可以选择将其定义为类的成员函数或非成员函数。

    • 如果将二元运算符定义为类的成员函数,参数列表将包括一个额外的参数,表示右侧操作数。左侧操作数则是隐式的this指针。

    • 如果将二元运算符定义为非成员函数(全局函数或友元函数),参数列表将包括两个参数,分别表示左侧和右侧操作数。

5. 全局运算符重载函数

我们依旧对比两个日期是否相等,判断大小,注意与上述代码的参数差异。

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;
};//operator运算符 做函数名
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 < 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;
}
int main()
{Date d1(2024, 1, 28);Date d2(2024, 1, 29);cout << operator == (d1, d2) << endl;cout << operator < (d1, d2) << endl;cout << (d1 == d2) << endl;cout << (d1 < d2) << endl;return 0;
}

6. 赋值运算符重载

6.1 语法及概念

赋值运算符重载是一种特殊的运算符重载,用于在自定义的类中重载"="运算符,使其能够对类对象进行正确的赋值操作。

赋值运算符重载的语法如下:

class ClassName {
public:ClassName& operator=(const ClassName& other) {// 执行赋值操作的代码return *this;}
};

在赋值运算符重载函数中,通常需要执行以下操作:

  1. 检查是否是自我赋值,即当前对象和要赋值的对象是否是同一个对象。如果是同一个对象,则直接返回当前对象,避免不必要的操作。

  2. 进行属性的深拷贝,将要赋值的对象的属性逐个复制给当前对象的属性。

  3. 返回当前对象的引用。

6.2 示例

class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}void Print(){cout << _year << '/' << _month << '/' << _day << endl;}Date& operator=(const Date& d){if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;}private:int _year;int _month;int _day;
};int main()
{Date d1(2024, 2, 01);Date d2(2024, 2, 02);Date d3(2024, 2, 03);d1 = d2 = d3;d1.Print();d2.Print();d3.Print();return 0;
}

6.3 为何使用引用

  1. 引用参数:赋值运算符需要修改当前对象的值,而不是创建一个新的对象。因此,使用引用参数,可以直接修改当前对象而不是在函数内部创建一个副本。

  2. 返回this指针:赋值运算符一般返回当前对象的引用,即*this。这样可以实现连续赋值操作,例如 a = b = c。通过返回this指针,可以链式调用赋值运算符。

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

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

相关文章

面试数据结构与算法总结分类+leetcode目录【基础版】

&#x1f9e1;&#x1f9e1;&#x1f9e1;算法题目总结&#xff1a; 这里为大家总结数据结构与算法的题库目录&#xff0c;如果已经解释过的题目会标注链接更新&#xff0c;方便查看。 数据结构概览 Array & String 大家对这两类肯定比较清楚的&#xff0c;同时这也是面试…

SVDiff: Compact Parameter Space for Diffusion Fine-Tuning——【论文笔记】

本文发表于ICCV 2023 论文地址&#xff1a;ICCV 2023 Open Access Repository (thecvf.com) 官方代码&#xff1a;mkshing/svdiff-pytorch: Implementation of "SVDiff: Compact Parameter Space for Diffusion Fine-Tuning" (github.com) 一、Introduction 最近几…

java反射详解

动态代理 什么是动态代理&#xff1f; 特点&#xff1a;无侵入式的给代码增加额外的功能 对象有什么方法想要被代理&#xff0c;代理就一定要有对应的方法 对象和代理需要实现同一个接口&#xff0c;接口中就是被代理的方法 调用者通过代理&#xff0c;调用代理中的方法&#x…

高级FPGA开发之基础协议PCIe

基础协议之PCIe部分 一、TLP包的包头 在PCIe的系统中&#xff0c;tlp包的包头的结构有许多部分是相似的&#xff0c;通过掌握这些常规的包头&#xff0c;能帮助理解在PCIe总线上各个设备之间如何进行数据的收发。 通用的字段 通用字段作用Fmt决定了包头是3DW还是3DW&#xff…

2V2无人机红蓝对抗仿真

两架红方和蓝方无人机分别从不同位置起飞&#xff0c;蓝方无人机跟踪及击毁红方无人机 2020a可正常运行 2V2无人机红蓝对抗仿真资源-CSDN文库

Android电动汽车充电服务vue+uniAPP微信小程序

本系统利用SSM和Uniapp技术进行开发电动汽车充电服务系统是未来的趋势。该系统使用的编程语言是Java&#xff0c;数据库采用的是MySQL数据库&#xff0c;基本完成了系统设定的目标&#xff0c;建立起了一个较为完整的系统。建立的电动汽车充电服务系统用户使用浏览器就可以对其…

Python爬虫urllib详解

前言 学习爬虫&#xff0c;最初的操作便是模拟浏览器向服务器发出请求&#xff0c;那么我们需要从哪个地方做起呢&#xff1f;请求需要我们自己来构造吗&#xff1f;需要关心请求这个数据结构的实现吗&#xff1f;需要了解 HTTP、TCP、IP 层的网络传输通信吗&#xff1f;需要知…

华清远见嵌入式学习——春节作业——2.4日

作业要求&#xff1a; 编写程序实现二叉树的创建&#xff0c;三种遍历自己销毁 作业答案&#xff1a; 作业代码截图 作业代码效果图 作业代码 #include "myhead.h"// 定义二叉树节点结构体 struct Tree {int value; //编号(值)struct Tree* left; //左子树stru…

idea创建spring项目

一、环境 window10 IDEA 2022.2.3 maven-3.8.6 二、创建spring项目 1、新建Maven项目 File -> New -> Project 然后如下图选中Maven Archetype&#xff0c;在Archetype&#xff0c;选中maven-archetype-webapp&#xff0c;点击Create 2、配置maven 默认是使用IDEA内…

管理类联考-复试-英语-听力

文章目录 准备工作1.如何准备英语听力&#xff1f;2.听力学习注意事项一&#xff1a;培养良好的听音习惯&#xff0c;听读顺序要合理3.听力学习注意事项二&#xff1a;边听边记关键词 训练短期记忆能力4.听力学习注意事项三&#xff1a;熟记语篇衔接词把握信息走向5.听力学习注…

少儿编程 中国电子学会图形化编程2022年1月等级考试Scratch三级真题解析(选择题、判断题)

1.默认小猫角色和气球角色都是显示状态&#xff0c;小猫程序如下图所示&#xff0c;气球没有程序&#xff0c;点击绿旗&#xff0c;舞台上最终显示的效果是&#xff1f;&#xff08; &#xff09; A&#xff1a;可能出现6个不同位置的小猫和6个小球 B&#xff1a;可能出现6个…

Multisim14.0仿真(四十九)共阴极/阳极7段数码管驱动设计

一、74LS47/48简介: 74LS47/48芯片是一种常用的七段数码管译码器驱动器,常用在各种数字电路和单片机系统的显示系统中. 二、74LS47/48引脚说明及定义: 7段显示译码器74LS47/48是输出低/高电平有效的译码器,74LS47/48除了有实现7段显示译码器基本功能的输入(DCBA)和输出(Ya…

Unity类银河恶魔城学习记录1-9 PlayerWallSilde源代码 P36

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili Player.cs using System.Collections; using System.Collections.Generic; using Unity.VisualScripting; us…

gerrit 安装插件

1.插件下载 gerrit 3.9 插件&#xff0c;打开链接去右上角搜索插件名称&#xff0c;找到合适的版本&#xff0c;由于我这儿需要安装gerrit 3.9.1 的 autosubmitter 插件&#xff0c;但是好像没有 3.9 的&#xff0c;有下面这俩 上面那个可以理解为基于插件的主分支代码进行构…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之MenuItemGroup组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之MenuItemGroup组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、MenuItemGroup组件 该组件用来展示菜单MenuItem的分组。 子组件 无 接…

高通android设备themal读取cpu温度

以msm8953的themal分布信息&#xff0c;主要是下图的位置&#xff1a; 这其中 cpu相关的themal的位置有&#xff1a; 读取thermal 温度数据可以通过以下几个步骤&#xff1a; 获取sensor_info rootmsm8953_64:/ # cat /sys/module/msm_thermal/sensor_info tsens:tsens_tz_se…

我用全志V851s做了一个魔法棒,使用Keras训练手势识别模型控制一切电子设备

这是一个可以直接启动原神的魔法棒~ 原神&#xff0c;启动&#xff01; 这是一个万全的解决方案&#xff01;只需要花80元再动动手&#xff0c;就可以将哈利波特的魔杖与人工智能结合到一起&#xff01;它就是用全志V851s做的赛博魔杖&#xff01; 这个魔法手杖有啥亮点 手势…

Go协程揭秘:轻量、并发与性能的完美结合

目录 1. Go协程简介什么是Go协程&#xff1f;Go协程与线程的比较Go协程的核心优势 2. Go协程的基本使用创建并启动Go协程使用匿名函数创建Go协程Go协程与主函数 3. Go协程的同步机制1. 通道 (Channels)2. sync.WaitGroup3. 互斥锁 (sync.Mutex) 4. Go协程的高级用法1. 选择器 (…

每日一题——LeetCode1394.找出数组中的幸运数

方法一 桶数组计数法 又要保存整数的数值和他出现的频次&#xff0c;那么碰到一个整数num就让res[num]&#xff0c;那么循环res数组&#xff0c;如果res[i]0则代表i没有在arr中出现过&#xff0c;res[i]n则代表i在arr中出现n次 因为题目要求只返回最大的幸运数&#xff0c;所…

计算机软件能力认证考试CCF-202312-1 仓库规划

#自己跑的测试没问题&#xff0c;不知道为啥就是不能满分 原理比较绕&#xff0c;就是让数组中一行不断地与其他行进行比较&#xff0c;最终得到各自的索引 #include <iostream> using namespace std; int main() {int n;int m;cin>>n>>m; int array[n][m];…