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

C/C++学习笔记十三 C++中的重载运算符

1、什么是运算符重载?

        运算符重载是 C++ 中的一项功能,使运算符(例如 +、- 等)能够处理用户定义的数据类型。这种机制称为编译时多态性,并提供了为不同数据类型定制运算符行为的优点。

        例如,我们可以重载“+”运算符来执行整数加法、字符串串联以及复数加法。这增强了运算符的多功能性,使他们能够对更广泛的数据类型进行操作。

2、什么是运算符函数?

        运算符函数是一种专门类型的函数,它为特定运算符提供替代实现。它的语法与常规函数类似,但其名称以“operator”关键字开头,后跟运算符符号。

        我们可以为同一个运算符定义多个运算符函数,这些函数可以根据它们所使用的操作数的数量和类型来区分。例如,“+”运算符可以针对整数、字符串和复数具有不同的运算符函数实现。这允许对操作员进行定制以满足特定要求。

class ClassName 
{...publicReturnType operator OperatorSymbool(argument list) {// Implementation logic} ...
};

        ReturnType: 运算符函数返回值的类型。

        运算符:编程语言中用于执行特定操作的关键字。

        OperatorSymbol:程序中重载的运算符的符号。

        参数列表:调用函数时传递给函数的参数列表。

3、使用运算符重载将两个复数相加

        假设我们不使用运算符重载并且想要将两个复数相加。我们可以通过创建一个名为“Complex”的复数类来实现这一点。在类内部,我们定义了一个名为“add”的公共方法,它执行两个复数的加法。此方法将接受两个复数作为参数,并将它们相加的结果作为新的复数返回。

class Complex {public:Complex add(Complex c1, Complex c2) {// Perform addition of c1 and c2 and return the resultreturn result;}
};//This approach works.
//But it requires us to call add method
Complex c1, c2, res;
res = c1.add(c1, c2);

        众所周知,运算符重载允许我们更改运算符的行为以处理用户定义的数据类型。因此,对于复数重载“+”运算符,我们可以在“Complex”类中定义一个运算符重载函数。

        此函数将指定“+”运算符与复数一起使用时的新行为。该函数可以定义为类的成员函数或友元函数,具体取决于运算符及其所操作的操作数的具体要求。

        定义完运算符函数后,我们现在可以使用简单的语句将两个复数 c1 和 c2 相加:res = c1 + c2,这相当于 res = c1.operator+ (c2)。这使得代码更直观、更容易理解。

#include <iostream>
using namespace std;class Complex {private:int real, imag;public:Complex(int r = 0, int i = 0) {real = r;imag = i;}Complex operator + (Complex c) {Complex temp;temp.real = real + c.real;temp.imag = imag + c.imag;return temp;}int getReal(){return real;}int getImag(){return imag;}
};int main() {Complex c1(4, 7);Complex c2(3, 5);Complex res;res = c1 + c2;cout << "Result: " << res.getReal() << " + " << res.getImag() << "i" << endl;return 0;
}//output Result: 7 + 12i

        我们还可以将函数签名写成如下:

Complex operator + (const Complex& c)

        这个版本与之前的版本有几个显着的区别:

  • 参数“c”使用“&”运算符通过引用传递,这意味着该函数将接收到原始对象的直接链接而不是副本。
  • 参数“c”也被指定为“const”,表示该函数不能更改它所传递的对象。

        这些修改被认为是最佳实践,原因如下:

  • 通过引用传递对象,函数可以访问原始对象而无需创建重复对象,从而提高效率并避免创建新对象的不必要的开销。
  • 将对象指定为“const”有助于防止对该对象进行意外修改,从而降低代码中出现错误和意外行为的风险。

4、重载加法运算符的另一个例子

class opr 
{private:int a;float b;public:opr(int a, float b) {this->a = a;this->b = b;}opr operator + (opr test) {opr tmp(0, 0.0);tmp.a = a + test.a;tmp.b = b + test.b;return tmp;}void show() {cout << a << " " << b << '\n';}
};int main() 
{opr obj1(1, 3.3);opr obj2(2, 1.5);opr obj3;obj3 = obj1 + obj2;obj3.show();return 0;
}

5、运算符重载的一些规则

        在 C++ 中重载运算符时,需要记住几个重要规则:

        1、至少其中一个操作数必须是用户定义的数据类型。

        2、只有内置运算符才能重载。这意味着我们无法创建新的运算符,只能更改现有的运算符以使其工作方式不同。

        3、重载运算符不能有默认参数,空参数列表“()”除外。

        4、重载运算符不会影响其优先级或结合性。

        5、操作数的数量无法更改。例如,一元运算符保持一元,二元运算符保持二元。

        6、编译器会自动为每个类重载赋值运算符“=”。换句话说,不需要为赋值运算符创建单独的运算符函数。我们可以使用它来复制同一类的对象,类似于使用复制构造函数。

        7、重载运算符时,正确且一致地使用它们以使代码更具可读性和易于理解性至关重要。

6、一元运算符的运算符重载

        一元运算符是对单个操作数进行操作的运算符。自增运算符“++”和自减运算符“--”是一元运算符的示例。例如,增量运算符“++”将其操作数的值增加1。它可以用作前缀运算符(放置在操作数之前)或后缀运算符(放置在操作数之后)。

        例如:

int x = 5;
// x is incremented to 6, and y is set to 6
int y = ++x;
// x is incremented to 7, but z is set to the original value of x (6)
int z = x++;

        类似地,减运算符“--”将其操作数的值减1。它也可以用作前缀或后缀运算符。例如:

int x = 5;
// x is decremented to 4, and y is set to 4
int y = --x;
// x is decremented to 3, but z is set to the original value of x (4)
int z = x--;

7、重载自增运算符(++)的实现代码

        在下面的代码中,我们定义了一个名为“Value”的类,其中包含一个私有成员变量“count”。我们还定义了一个构造函数,将该成员变量初始化为值 2。在类内部,我们将“operator++”函数定义为成员函数,该函数被重载两次(带和不带 int 参数)。这些函数将“count”成员变量的值加 1。

        在 main 函数中,我们创建一个“Value”对象 (v) 并对其多次使用“++”运算符。然后,我们使用“getCount”方法来检索“count”成员变量的值。

class Value 
{private:int count;public:Value() : count(2) {}// prefix version of ++ operatorvoid operator ++ () {++count;}// postfix version of ++ operatorvoid operator ++ (int) {++count;}int getCount() {return count;}
};int main() 
{Value v;v++;cout << v.getCount() << "\n";++v;++v;cout << v.getCount() << "\n";return 0;
}//output 
//3
//5

        一元运算符函数的前缀和后缀版本之间的唯一区别是参数列表。前缀版本不带参数,而后缀版本带一个“int”类型的参数。该参数实际上并不用于传递整数值,而是向编译器发出信号,指示该函数应用于重载运算符的后缀形式。

8、C++中实现运算符重载的三种方法

        (1)、通过成员函数重载运算符

        成员函数是在类内部定义并作用于该类的对象的函数。关于运算符重载,一元运算符(对单个参数进行操作的运算符)在其列表中没有参数,而二元运算符(对两个参数进行操作的运算符)只有一个参数。

class Complex 
{private:double real;double imag;public:Complex(double real = 0, double imag = 0) : real(real), imag(imag) {}// overload the + operator as a member functionComplex operator + (const Complex& other) const {return Complex(real + other.real, imag + other.imag);}void print() const {cout << real << " + " << imag << "i" << endl;}
};int main() 
{Complex c1(1, 2);Complex c2(3, 4);Complex c3 = c1 + c2;c3.print();return 0;
}
        (2)、通过友元函数重载运算符

        友元函数不是类的成员,但可以直接访问私有和受保护成员,并且可以在类的私有或公共部分中声明。与成员函数相比,它提供了更大的灵活性。

        换句话说,如果运算符函数需要访问类的私有和受保护成员,则可以将其定义为友元函数。在这种情况下,一元运算符有一个参数,而二元运算符有两个参数。

class Complex 
{private:double real;double imag;public:Complex(double real = 0, double imag = 0) : real(real), imag(imag) {}friend Complex operator + (const Complex& c1, const Complex& c2);void print(){cout << real << " + " << imag << "i" << endl;}
};// overload the + operator as a friend function
Complex operator + (const Complex& c1, const Complex& c2) 
{return Complex(c1.real + c2.real, c1.imag + c2.imag);
}int main() 
{Complex c1(1, 2);Complex c2(3, 4);Complex c3 = c1 + c2;c3.print();return 0;
}
        (3)、通过非成员函数重载运算符

        非成员函数不是类的成员,无权访问私有成员和受保护成员。

class Complex 
{public:double real;double imag;Complex(double real = 0, double imag = 0) : real(real), imag(imag) {}void print() const {cout << real << " + " << imag << "i" << endl;}
};// overload the + operator as a non-member function
Complex operator + (const Complex& c1, const Complex& c2) 
{return Complex(c1.real + c2.real, c1.imag + c2.imag);
}int main() 
{Complex c1(1, 2);Complex c2(3, 4);Complex c3 = c1 + c2;c3.print();return 0;
}

相关文章:

C/C++学习笔记十三 C++中的重载运算符

1、什么是运算符重载&#xff1f; 运算符重载是 C 中的一项功能&#xff0c;使运算符&#xff08;例如 、- 等&#xff09;能够处理用户定义的数据类型。这种机制称为编译时多态性&#xff0c;并提供了为不同数据类型定制运算符行为的优点。 例如&#xff0c;我们可以重载“”运…...

Java 实现自动获取法定节假日

一、背景 在实现业务需求的过程中&#xff0c;遇到了需要计算 x 个工作日后的日期需求。由于工作日是每年国务院发布的&#xff0c;调休和休假都没有规律&#xff0c;所以无法使用算法进行计算。 一般的实现方案是自己维护一个工作日和调休的表&#xff0c;或者去爬取国务院发…...

湘潭大学-2023年下学期-c语言-作业0x0a-综合1

A 求最小公倍数 #include<stdio.h>int gcd(int a,int b) {return b>0?gcd(b,a%b):a; }int main() {int a,b;while(~scanf("%d%d",&a,&b)){if(a0&&b0) break;printf("%d\n",a*b/gcd(a,b));}return 0; }记住最大公约数的函数&…...

网络协议-BIO实战和NIO编程

网络通信编程基本常识 在开发过程中&#xff0c;如果类的名字有 Server 或者 ServerSocket 的&#xff0c;表示这个类是给服务端容纳网络 服务用的&#xff0c;如果类的名字只包含 Socket 的&#xff0c;那么表示这是负责具体的网络读写的。 ServerSocket 并不负责具体的网络读…...

Word 将页面方向更改为横向或纵向

文章目录 更改整个文档的方向更改部分页面的方向方法1&#xff1a;方法2&#xff1a; 参考链接 更改整个文档的方向 选择“布局”>“方向”&#xff0c;选择“纵向”或“横向”。 更改部分页面的方向 需要达到下图结果&#xff1a; 方法1&#xff1a; 选:中你要在横向页面…...

关键字:abstract关键字

在 Java 中&#xff0c;abstract是一个关键字&#xff0c;用于修饰类和方法。当一个类被声明为抽象类时&#xff0c;它不能被实例化&#xff0c;只能被其他类继承。同时&#xff0c;抽象类可以包含抽象方法&#xff0c;抽象方法没有方法体&#xff0c;只包含方法的签名&#xf…...

从PDF中提取图片

由于工作需要&#xff0c;要从pdf文件中提取出图片保存到本地&#xff0c;项目中就引用到了Apache PDFBox库。 1 什么是Apache PDFBox? Apache PDFBox库&#xff0c;一个用于处理PDF文档的开源Java工具。它允许用户创建全新的PDF文件&#xff0c;操作现有的PDF文档&#xff0…...

推荐:一个不错的介绍Apache Doris的PPT

原来Apache Doris居然是百度开源出来的&#xff0c;不错。部分节选&#xff1a;完整下载地址网盘&#xff1a; 链接: https://pan.baidu.com/s/18WR70R_f72GxCjh0lykStQ 提取码: umd3 复制这段内容后打开百度网盘手机App&#xff0c;操作更方便哦 --来自百度网盘超级会员v7的分…...

【Python_PySide2学习笔记(二十二)】进度对话框QProgressDialog类的基本用法

进度对话框QProgressDialog类的基本用法 进度对话框QProgressDialog类的基本用法前言一、QProgressDialog 的常用方法1、创建进度对话框2、进度对话框设置窗口标题3、进度对话框隐藏"最大化"、"最小化"、"关闭"4、进度对话框设置是否自动关闭5、…...

使用rust读取usb设备ACR122U的nfc卡片id

rust及其高效和安全著称&#xff0c;而且支持跨平台&#xff0c;所以就想使用这个rust开发一个桌面端程序&#xff0c;来读取nfc设备的nfc卡片的id信息&#xff0c;下面就做一个最简单的入门教程吧&#xff0c;也是我写的第三个rust应用。 当你电脑上安装好了rust环境之后&…...

servlet总结

目录 1.生命周期 2.线程总结 3.配置 4.请求和响应 5.会话管理 6.过滤和监听器 7.处理表单数据 8.与JSP集成 9.异常处理 10.安全性和认证 Servlet是一种基于Java的Web组件&#xff0c;用于处理客户端请求并生成动态Web内容。以下是关于Servlet的一些总结 1.生命周期 …...

Nacos2.1.2改造适配达梦数据库7.0

出于业务需求&#xff0c;现将Nacos改造适配达梦数据库7.0&#xff0c;记录本次改造过程。 文章目录 一、前期准备二、适配流程1、项目初始化2、引入驱动3、源码修改 三、启动测试四、打包测试 一、前期准备 Nacos源码&#xff0c;版本&#xff1a;2.1.2&#xff1a;源码下载…...

TPRI-DMP平台介绍

TPRI-DMP平台介绍 1 TPRI-DMP平台概述 TPRI-DMP为华能集团西安热工院自主产权的工业云PaaS平台&#xff0c;已经过13年的发展和迭代&#xff0c;其具备大规模能源电力行业生产应用软件开发和运行能力。提供TPRI-DMP平台主数据管理、业务系统开发与运行、应用资源管理…...

oracle-存储结构

文件包括 控制文件.ctl、数据文件.dbf、日志文件.log这三类放在存储上。 参数文件&#xff1a;空间的划分&#xff0c;进程的选用&#xff08;.ora&#xff09; oracle启动的时候需要读一下&#xff0c;数据库启动后&#xff0c;参数文件并不关闭&#xff0c;但即使文件丢了&a…...

获取PG库 database与 user 创建时间以及cluster初始化时间

代码实现 echo "获取数据库创建时间" data_dir$(psql -U postgres -d postgres -X -qAt -c "show data_directory" ) db_dirs$(ls $data_dir/base |grep -v pgsql_tmp) for db_oid in $db_dirs dodb_exists$(psql -U postgres -d postgres -X -qAt -c &qu…...

【12.29】转行小白历险记-刷算法05

242.有效的字母异位词 数组、set、map&#xff0c;数组是比较高效查找的 函数功能 判断字符串 s 和 t 是否互为字母异位词。如果它们包含相同的字符且每个字符出现的次数也相同&#xff0c;那么它们互为字母异位词。 代码逻辑 长度检查&#xff1a; if (s.length ! t.lengt…...

docker部署kafka zookeeper模式集群

单机模式链接&#xff1a;https://blog.csdn.net/wsdhla/article/details/133032238 kraft集群模式链接&#xff1a;部署Kafka_kafka 部署-CSDN博客 zookeeper选举机制举例&#xff1a; 目前有5台服务器&#xff0c;每台服务器均没有数据&#xff0c;它们的编号分别是1,2,3,4,5…...

Apache Flink连载(二十一):Flink On Yarn运行原理-Yarn Application模式

🏡 个人主页:IT贫道_大数据OLAP体系技术栈,Apache Doris,Clickhouse 技术-CSDN博客 🚩 私聊博主:加入大数据技术讨论群聊,获取更多大数据资料。 🔔 博主个人B栈地址:豹哥教你大数据的个人空间-豹哥教你大数据个人主页-哔哩哔哩视频 目录 1. 任务提交命令...

《深入理解C++11:C++11新特性解析与应用》笔记五

第五章 提高类型安全 5.1 强类型枚举 5.1.1 枚举&#xff1a;分门别类与数值的名字 具名枚举类型一般声明类似&#xff1a;enum Gender { Male, Female }。 匿名枚举类型可以使用三种方式实现&#xff1a; 第一种方式时宏&#xff0c;比如 #define Male 0 #define Femal…...

Y9000P + ubuntu22.04 配置Anaconda+pycharm +pytorch

Anaconda3 的安装及使用方法安装 Anaconda3 Anaconda3 是 Anaconda 的具体版本 Anaconda3 中的 Python 解释器默认使用的是 Python3.x 版本&#xff0c;而不是 Python2.x 版本 Python2.x 版本中&#xff0c;字符串是以 ASCII 编码处理的&#xff0c;而在 Python3.x 版本中&am…...

使用Ubuntu编译FFmpeg生成Android动态库/静态库

环境 我这里使用windows里的wsl2的ubuntu&#xff0c;使用物理机或者vmware&#xff0c;vbox之类的安装的ubuntu理论上也可以. gcc编译使用的环境如下: Ndk使用17 FFmpeg使用4.0.2. clang编译使用的环境如下: Ndk使用21.4 FFmpeg使用6.1 FFmpeg下载地址:https://ffmpeg.org/…...

【AIGC-图片生成视频系列-2】八仙过海,各显神通:AI生成视频相关汇总剖析

最近「图片生成视频系列」层出不穷&#xff0c;我拜读并结合实践&#xff08;对&#xff0c;就是手撕代码&#xff0c;有开源就撕&#xff09;&#xff0c;并对以下几篇文章的相似点以及关键点稍微做个总结&#xff1a; 一. 生成视频中图像的一致性 在图像生成视频的这个过程…...

SpringBoot集成RabbitMq消息队列【附源码】

1. 项目背景 要啥项目背景&#xff0c;就是干&#xff01;&#xff01;&#xff01; SpringBoot版本&#xff1a;2.7.12 2. Rabbit MQ安装 这里讲解使用docker安装RabbitMQ&#xff0c;如果在windows下面安装RabbitMQ&#xff0c;参考下文 【笑小枫的按步照搬系列】Window…...

MySQL数据库的安装与环境配置

下载 下载MySQL8 安装 解压 配置MySQL环境变量 系统环境变量path D:\ProgramFiles\mysql-8.0.20-winx64\bin 1.点击属性 2.点击高级系统设置 3.点击环境变量 4.在系统变量中找到path 注意这里不是用户变量 5.新建后输入解压的地址 MySQL初始化和启动 以管理员身份运行cmd…...

【广州华锐互动】VR科技科普展厅平台:快速、便捷地创建出属于自己的虚拟展馆

随着科技的不断进步&#xff0c;虚拟现实(VR)技术已经在许多领域取得了显著的成果。尤其是在展馆设计领域&#xff0c;VR科技科普展厅平台已经实现了许多令人瞩目的新突破。 VR科技科普展厅平台是广州华锐互动专门为企业和机构提供虚拟展馆设计和制作的在线平台。通过这个平台&…...

XML Extension Supplement

LEGAL ISSUES, COMPANY POLICIES AND STANDARDS Web Services A Web service is a software system designed to support interoperable machine-to-machine interaction over a network. URI和URL URI&#xff0c;全称是统一资源标识符&#xff08;Uniform Resource Ident…...

手拉手Springboot获取yml配置文件信息

环境介绍 技术栈 springboot3 软件 版本 mysql 8 IDEA IntelliJ IDEA 2022.2.1 JDK 17 Spring Boot 3.1.7 配置文件说明&#xff1a;启动配置文件优先级&#xff1a;properties高于yml 配置文件application.yml yml是 JSON 的超集&#xff0c;简洁而强大&#xf…...

行人重识别(ReID)基础知识入门

这里写目录标题 1、ReID技术概述1.1 基本原理1.2 实现流程1.3 重识别存在的技术挑战 2、训练数据格式介绍 1、ReID技术概述 1.1 基本原理 ReID&#xff0c;全称Re-identification&#xff0c;目的是利用各种智能算法在图像数据库中找到与要搜索的目标相似的对象。ReID是图像检…...

【音视频 ffmpeg 学习】 跑示例程序 持续更新中

环境准备 在上一篇文章 把mux.c 拷贝到main.c 中 使用 attribute(unused) 消除警告 __attribute__(unused)/** Copyright (c) 2003 Fabrice Bellard** Permission is hereby granted, free of charge, to any person obtaining a copy* of this software and associated docu…...

前端axios与python库requests的区别

当涉及到发送HTTP请求时&#xff0c;Axios和Python中的requests库都是常用的工具。下面是它们的详细说明&#xff1a; Axios&#xff1a; Axios是一个基于Promise的HTTP客户端&#xff0c;主要用于浏览器和Node.js环境中发送HTTP请求。以下是Axios的一些特点和用法&#xff1…...

ubuntu wordpress安装目录/百度快照优化

前段时间学习《深入浅出Nodejs》时&#xff0c;在第四章 - 异步编程中作者朴灵曾提到&#xff0c;异步编程的难点之一是异常处理&#xff0c;书中描述"尝试对异步方法进行try/catch操作只能捕获当次事件循环内的异常&#xff0c;对call back执行时抛出的异常将无能为力&qu…...

充值网站制作/最新中高风险地区名单

转载请注明出处&#xff1a;http://blog.csdn.net/u011733020前言&#xff1a;在Android开发中&#xff0c;对于图片的加载可以说是个老生常谈的问题了&#xff0c;图片加载是一个比较坑的地方&#xff0c;处理不好&#xff0c;会有各种奇怪的问题&#xff0c;比如 加载导致界面…...

中山网站建设文化策划书/nba东西部最新排名

一、视图语法&#xff1a;create view 视图名称 as 子查询例&#xff1a;创建一视图&#xff0c;包含全部的20部门的雇员信息(雇员编号&#xff0c;姓名&#xff0c;工作&#xff0c;雇佣日期)create view emp20 as select empno,ename,job,hiredate from emp wheredeptno 20;…...

7k7k网页游戏入口/北京seo优化哪家好

Hibernate是一个持久层的框架&#xff0c;主要用于数据的存储&#xff0c;简单的使用步骤。 1、基于MVC设计模式分包 ①com.web.bean 主要存放实体类也就是表和类之间的映射关系&#xff0c;实体类中有表中相应的字段&#xff0c;提供get/set方法&#xff0c;实现序列化接口&am…...

美食网站开发的目标/外链工厂 外链

TITLE: SQL Server 安装程序失败。 ------------------------------ SQL Server 安装程序遇到以下错误: MsiGetProductInfo 无法检索 Product Code 为“{95120000-00B9-0409-0000-0000000FF1CE}”的包的 ProductVersion。错误代码: 1605。。 遇到这个错误时&#xff0c;解决方…...

wordpress会员文章/google关键词工具

云计算带来的是IT产业的转型和升级。不仅各个微观经济实体成为了云计算产业链中的参与者&#xff0c;各国政府也同样重视这一产业的重要变革。   毕竟&#xff0c;就如同制造业的变革导致了全球范围的重新分工&#xff0c;云计算的出现也将引发IT产业在世界范围内的再分工。 …...