当前位置: 首页 > news >正文

【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指针,可以链式调用赋值运算符。

相关文章:

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

&#x1f497;个人主页&#x1f497; ⭐个人专栏——C学习⭐ &#x1f4ab;点击关注&#x1f929;一起学习C语言&#x1f4af;&#x1f4ab; 目录 导读 1. 为什么需要运算符重载 2. 运算符重载概念 3. 运算符重载示例 3.1 运算符重载 3.2 >或<运算符 4. 运算符重…...

评论区功能的简单实现思路

评论区功能是社交类项目中的核心组成部分&#xff0c;它涉及到前端的交云和后端的数据处理。基于你的技术栈&#xff08;前端 Vue3&#xff0c;后端 Java&#xff09;&#xff0c;下面是一个具体的实现思路和数据库设计建议&#xff0c;并探索一下知乎的评论系统。 数据库设计…...

Java自救手册

目录 访问地址 访问地址&#xff0c;发现不通&#xff0c;无法访问&#xff1a; 网络不通一般有两种情况&#xff1a; Maven 拿Maven 拿到Maven以后 Maven单独的报红 Git git注意&#xff1a; 目录 访问地址 访问地址&#xff0c;发现不通&#xff0c;无法访问&…...

ASM-HEMT参数提取和模型验证测试

参数提取程序 直流I-V参数提取 DC模型参数提取流程对于ASM-GaN-HEMT模型可以总结在下图中。 以下步骤描述了该流程&#xff1a; 在模型中设置物理参数&#xff0c;如L&#xff08;沟道长度&#xff09;、W&#xff08;沟道宽度&#xff09;、NF&#xff08;栅指数&#xf…...

浅压缩、深压缩、双引擎、计算机屏幕编码……何去何从?

专业视听领域尤其显示控制和坐席控制领域&#xff0c;最近几年最激动人心的技术&#xff0c;莫过于分布式了。 分布式从推出之日就备受关注&#xff1a;担心稳定性的&#xff0c;质疑同步性能的&#xff0c;怀疑画面质量的…… 诚然&#xff0c;我们在此前见多了带着马赛克的…...

2020年通信工程师初级专业实务真题

文章目录 一、第1章 现代通信网概述&#xff1a;信令网、同步网、管理网。第10章 通信业务&#xff1a;通信产业链&#xff0c;通信终端的分类&#xff0c;通信业务的定义及分类二、第3章 接入网&#xff1a;无线接入网的优点&#xff0c;接入网的接口&#xff08;UNI&#xff…...

Linux常见面试题汇总

Linux上如何查询某个端口是否被占用&#xff1f; 在Linux上&#xff0c;你可以使用以下几种方法来查询某个端口是否被占用&#xff1a; 使用netstat命令&#xff1a; netstat -tuln | grep <端口号>这个命令会列出当前正在运行的所有TCP和UDP端口&#xff0c;并过滤出指…...

C语言小游戏:贪吃蛇(游戏开发的环境和功能介绍)

❀❀❀ 文章由不准备秃的大伟原创 ❀❀❀ ♪♪♪ 若有转载&#xff0c;请联系博主哦~ ♪♪♪ ❤❤❤ 致力学好编程的宝藏博主&#xff0c;代码兴国&#xff01;❤❤❤ 生命不停&#xff0c;学习不止。铁汁们&#xff0c;我是大伟&#xff0c;欢迎来到大伟的游戏时间&#xff0c…...

ElementUI Form:InputNumber 计数器

ElementUI安装与使用指南 InputNumber 计数器 点击下载learnelementuispringboot项目源码 效果图 el-radio.vue &#xff08;InputNumber 计数器&#xff09;页面效果图 项目里el-input-number.vue代码 <script> export default {name: el_input_number,data() {re…...

apk反编译修改教程系列---修改apk的默认颜色 布局颜色 手机电脑同步演示【十】

往期教程&#xff1a; apk反编译修改教程系列-----修改apk应用名称 任意修改名称 签名【一】 apk反编译修改教程系列-----任意修改apk版本号 版本名 防止自动更新【二】 apk反编译修改教程系列-----修改apk中的图片 任意更换apk桌面图片【三】 apk反编译修改教程系列---简单…...

响应式开发如何设置断点,小屏幕界面该如何显示(有动图)

Hi&#xff0c;我是贝格前端工场&#xff0c;本期分享响应式开发&#xff0c;如何设置屏幕断点&#xff0c;pc页面布局到了移动端之后该如何布局的问题&#xff0c;微软也提供了设置屏幕断点的动图演示&#xff0c;非常直观。 一、什么是响应式开发&#xff0c;为何要设置屏幕断…...

Java基础 集合(二)List详解

目录 简介 数组与集合的区别如下&#xff1a; 介绍 AbstractList 和 AbstractSequentialList Vector 替代方案 Stack ArrayList LinkedList 前言-与正文无关 生活远不止眼前的苦劳与奔波&#xff0c;它还充满了无数值得我们去体验和珍惜的美好事物。在这个快节奏的世界…...

UE4运用C++和框架开发坦克大战教程笔记(十七)(第51~54集)

UE4运用C和框架开发坦克大战教程笔记&#xff08;十七&#xff09;&#xff08;第51~54集&#xff09; 51. UI 框架介绍UE4 使用 UI 所面临的问题以及解决思路关于即将编写的 UI 框架的思维导图 52. 管理类与面板类53. 预加载与直接加载54. UI 首次进入界面 51. UI 框架介绍 U…...

GaussDB新体验,新零售选品升级注入新思路【华为云GaussDB:与数据库同行的日子】

选品思维&#xff1a;低频VS高频 一个的商超&#xff0c;假设有50个左右的品类&#xff0c;每个品类下有2到10个不等的商品。然而如此庞大的商品&#xff0c;并非所有都是高频消费品。 结合自身日常的消费习惯&#xff0c;对于高频和低频的区分并不难。一般大型家电、高端礼盒…...

C语言问题汇总

指针 #include <stdio.h>int main(void){int a[4] {1,2,3,4};int *p &a1;int *p1 a1;printf("%#x,%#x",p[-1],*p1);} 以上代码中存在错误。 int *p &a1; 错误1&#xff1a;取a数组的地址&#xff0c;然后1&#xff0c;即指针跳过int [4]大小的字节…...

QT 的 blockSignals(true) 的作用范围

在 Qt 中&#xff0c;blockSignals 是一个用于控件的方法&#xff0c;它用于阻止控件发出的信号。如果你在一个 MainWindow 对象上调用 blockSignals(true)&#xff0c;它会阻止该 MainWindow 对象发出的所有信号。 这意味着&#xff0c;如果 MainWindow 上有任何子控件&#…...

【C++私房菜】类和对象万字详解

目录 一、类与对象 1、类是什么 二、类和对象的基础知识 2.1 定义类&#xff1a;成员变量和成员函数 2.2 创建对象&#xff1a;实例化一个类的对象。 2.3对象的生命周期&#xff1a;构造函数和析构函数。 a. 构造函数 b. 析构函数 c.小结&#xff1a; 三、成员变量和…...

PDF下载添加水印和访问密码

下载接口 ApiOperation(value "下载文件-pdf", notes "下载文件pdf版", httpMethod "GET", response WebResult.class)RequestMapping(value "/downloadPdf", method RequestMethod.GET)public void downloadFilePdf(RequestPar…...

基于SSM+MySQL的的新闻发布系统设计与实现

目录 项目简介 项目技术栈 项目运行环境 项目截图 代码截取 源码获取 项目简介 新闻发布系统是一款基于Servletjspjdbc的网站应用程序&#xff0c;旨在提供一个全面且高效的新闻发布平台。该系统主要包括后台管理和前台新闻展示两个平台&#xff0c;涵盖了新闻稿件的撰写…...

记录首次使用yolov8-obb

1.数据格式 之前使用的数据格式是yolov5_obb的数据格式&#xff0c;然后需要转数据格式&#xff1a; 目前的数据只支持四个坐标点标注的数据&#xff0c;参考&#xff1a;If a corner of the rotate rectangle is out of the image range, How to annotate the image? Issu…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

什么是VR全景技术

VR全景技术&#xff0c;全称为虚拟现实全景技术&#xff0c;是通过计算机图像模拟生成三维空间中的虚拟世界&#xff0c;使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验&#xff0c;结合图文、3D、音视频等多媒体元素…...

抽象类和接口(全)

一、抽象类 1.概念&#xff1a;如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象&#xff0c;这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法&#xff0c;包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中&#xff0c;⼀个类如果被 abs…...

书籍“之“字形打印矩阵(8)0609

题目 给定一个矩阵matrix&#xff0c;按照"之"字形的方式打印这个矩阵&#xff0c;例如&#xff1a; 1 2 3 4 5 6 7 8 9 10 11 12 ”之“字形打印的结果为&#xff1a;1&#xff0c;…...

从零开始了解数据采集(二十八)——制造业数字孪生

近年来&#xff0c;我国的工业领域正经历一场前所未有的数字化变革&#xff0c;从“双碳目标”到工业互联网平台的推广&#xff0c;国家政策和市场需求共同推动了制造业的升级。在这场变革中&#xff0c;数字孪生技术成为备受关注的关键工具&#xff0c;它不仅让企业“看见”设…...

PydanticAI快速入门示例

参考链接&#xff1a;https://ai.pydantic.dev/#why-use-pydanticai 示例代码 from pydantic_ai import Agent from pydantic_ai.models.openai import OpenAIModel from pydantic_ai.providers.openai import OpenAIProvider# 配置使用阿里云通义千问模型 model OpenAIMode…...