学习记录——day41 运算符重载

        运算符默认不支持自定义的类,但是可以通过运算符重载扩展运算符的属于范围

        运算符重载,也是实现泛型编程的一种,能够实现“一符多用”,可以使用运算符重载来完成对象与对象之间的符号运算

        注:运算符重载仅针对类对象 不影响基础数据类型

一、运算符重载函数

1)函数名:统一为 operator# //这里的#表示要被重载的运算符

2)参数:根据运算符的功能和位置而定,

         如:全局函数版双目运算符参数有两个,成员函数版双目运算符参数一个

                全局函数版,单目运算符参数有一个,成员函数版单目运算符参数无

3> 返回值:根据实际情况而定

二、调用原则和调用机制

        调用时机:当对象使用该运算符时,系统自动调用运算符重载函数

        调用机制:左调右参原则,运算符左侧是函数的调用者,运算符右侧是函数的参数

                                例如:a = b;       //a.operator=(b);

                                           s1 + s2;   //s1.operator+(s2);

下列以此类为例:

class Complax
{
private:
        int real;            //实部    
        int vir;             //虚部
public:
         ......
};

三、算数运算符重载

1)种类:+、-、*、/、%

2)算术运算符属于双目运算符,格式:L # R; L表示左操作数,#表示运算符号,R表示右操作数

3)左操作(L):既可以是左值也可以是右值

     右操作数(R):既可以是左值也可以是右值

     运算结果:只能是右值

4)格式:

成员函数版:const 类名 operator#(const 类名 &R) const

           解析:第一个const保护运算结果不被修改

                      第二个const保护右操作数在运算过程中不被修改

                      第三个const保护左操作数自身在运算过程中不被修改

全局函数版:const 类名 operator#(const 类名 &L,const 类名 &R)

以 + 为例      (参数、返回值、函数体内部逻辑根据实际情况改变)

成员函数版

class Complax
{
private:int real;            //实部    int vir;             //虚部
public://成员函数版const Complax operator+(const Complax &R)const{Complax temp;       //无参构造temp.real = this->real + R.real;temp.vir = this->vir + R.vir;return temp;}
};    

 全局函数版

//全局函数版class Complax
{
private:int real;            //实部    int vir;             //虚部
public://实现全局函数版,需要将全局函数版设置成友元函数friend const Complax operator+(const Complax &L, const Complax &R);
};const Complax operator-(const Complax &L, const Complax &R)
{Complax temp;       //无参构造temp.real = L.real - R.real;temp.vir = R.vir - R.vir;return temp;
}

四、赋值类运算符重载

1)种类:=、+=、-=、*=、/=、%=

2)赋值运算符属于双目运算符,格式:L # R; L表示左操作数,#表示运算符号,R表示右操作数

3)左操作(L):只能是左值

     右操作数(R):既可以是左值也可以是右值

     运算结果:左操作数自身的引用

4)格式:

        成员函数版:类名 & operator#(const 类名 &R)

        全局函数版:类名 & operator#( 类名 &L,const 类名 &R)

五、关系运算符重载函数

1)种类:>、=、

2)关系运算符属于双目运算符,格式:L # R; L表示左操作数,#表示运算符号,R表示右操作数

3)左操作(L):既可以是左值也可以是右值

     右操作数(R):既可以是左值也可以是右值

     运算结果:bool类型的右值

4)格式:

        成员函数版:const bool operator#(const 类名 &R) const

        全局函数版:const bool operator#(const 类名 &L,const 类名 &R)

六、单目运算符

1)种类:-(负号) 、!

2)格式:# R; #表示运算符号,R表示右操作数

3)操作数(R):既可以是左值也可以是右值

     运算结果:同类的一个右值

4)格式:

        成员函数版:const 类名 operator#() const

        全局函数版:const bool operator#(const 类名 &R)

七、自增自减运算

1)种类:++ 、 --

2)格式:# R; #表示运算符号,R表示右操作数

3)操作数(R):只能是左值

      运算结果:  

              前置:是自身的引用

                         成员格式:类名 &operator#()

                         全局格式:类名 &operator#(类名 &R)              

           

              后置:临时值

                         成员格式:类名 operator#(int)

                         全局格式:类名 operator#(类名 &R, int)

八、插入和提取运算符重载

1)插入和提取运算符的来源

namespace std
{
    ostream cout;
    istream cin;
}

2)由于运算符重载函数的调用遵循左调有参原则,所以,自定义类的重载函数,需要流对象和自定义类的对象

        例如:cout

3)此时,原则上来说,需要在流所在的类对象中,写成员函数,难度较大,所以,对于该类的重载函数,我们只能实现全局函数版,将该函数作为类的友元函数

4)由于不需要使用istream和ostream类中的私有成员,所以,全局函数版的重载函数不需要在流对应的类中,声明友元函数

        如果,重载函数中,需要使用自定义的类中的私有成员,则需要在自定义类中,声明该全局函数为友元函数

5)格式:

        ostream& operator

        istream& operator>>(istream &L, 类名 &R)

九、类型转换运算符

1)有时,需要将类对象进行强制类型转换为其他数据类型,此时就需要在类体内提供类型转换运算符重载函数

2)定义格式: operator 要转换的类型() { 返回对应类型的数据 }

十、函数对象(仿函数)

1)本质上就是重载 () 运算符,由于调用时,跟函数调用一样,所以称为仿函数

2)定义格式: operator() (参数列表) {函数体内容}

3)调用格式:对象名(实参名); //对象 . operator() (实参名)

十一、运算符重载的限制

1>不能重载运算符 ::(作用域解析)、.(成员访问)、.*(通过成员指针的成员访问)及 ?:(三元条件)。

2>不能创建新运算符,例如 **、<> 或 &|。

3>运算符 && 与 || 的重载失去短路求值。

4>重载的运算符 -> 必须要么返回裸指针,要么(按引用或值)返回同样重载了运算符 -> 的对象。

5>不可能更改运算符的优先级、结合方向或操作数的数量。

6>&&、|| 和 ,(逗号)在被重载时失去其特殊的定序性质,并且即使不使用函数调用记法,也表现为与常规的函数调用相似。
(C++17 前)

示例

#include <iostream>using namespace std;//定义一个复数类: 由实部和虚部组成的一个数据  a + bi
class Complax
{
private:int real;            //实部int vir;             //虚部public:Complax() {cout<<"无参构造"<<endl;}            //无参构造Complax(int r, int v):real(r),vir(v) {cout<<"有参构造"<<endl;}   //有参构造~Complax() {cout<<"析构函数"<<endl;}           //析构函数//定义输出函数void show(){if(vir > 0){cout<<real << "+"<<vir<<"i"<<endl;}else{cout<<real << vir<<"i"<<endl;}}//定义成员函数版完成两个复数相加:实部+实部   虚部+虚部const Complax operator+(const Complax &R)const{Complax temp;       //无参构造temp.real = this->real + R.real;temp.vir = this->vir + R.vir;return temp;}//实现全局函数版,需要将全局函数版设置成友元函数friend const Complax operator-(const Complax &L, const Complax &R);//成员函数版完成加等于运算符重载: 实部 += 实部   虚部+=虚部Complax &operator+=(const Complax &R){this->real += R.real;this->vir += R.vir;return *this;}//定义成员函数版完成关系运算符重载: 实部>实部   && 虚部>虚部bool operator>(const Complax &R)const{return this->real>R.real && this->vir>R.vir;}//定义成员函数版完成负号运算符重载:   实部 = -实部    虚部=-虚部const Complax operator-()const{Complax temp;temp.real = -this->real;temp.vir = -this->vir;return temp;}//定义成员函数版完成++前置运算: 实部 +=1   虚部+=1Complax &operator++(){this->real++;this->vir++;return *this;}//定义成员函数版完成++后置运算: 实部 +=1   虚部+=1Complax operator++(int)        //这里括号中的int仅仅起到占位作用,使用的是哑元{Complax temp;temp.real = this->real++;temp.vir = this->vir++;return temp;}//将插入运算符重载函数,设置成友元函数friend ostream & operator<<(ostream &L, const Complax &R);//定义类型转换运算符重载函数operator int(){return this->real + this->vir;}//重载小括号运算符,完成仿函数void operator()(string msg){cout << msg<< endl;}};//定义全局函数版完成两个复数相减
const Complax operator-(const Complax &L, const Complax &R)
{Complax temp;       //无参构造temp.real = L.real - R.real;temp.vir = R.vir - R.vir;return temp;
}//自定义插入运算符重载函数:只能实现全局函数版
ostream & operator<<(ostream &L, const Complax &R)
{//输出内容if(R.vir > 0){L<<R.real << "+"<<R.vir<<"i"<<endl;}else{L<<R.real << R.vir<<"i"<<endl;}//返回左操作数自身return L;
}int main()
{Complax c1(5,7);           //有参构造c1.show();                //5+7iComplax c2(3, -2);            //有参构造c2.show();                    //3-2icout<<"**************************************"<<endl;Complax c3 = c1+c2;       //调用加号 运算符重载函数c3.show();                //8+5icout<<"**************************************"<<endl;(c1+=c2) += c3;          //调用加等于运算符重载函数c1.show();            //16+10ic2.show();             //3-2ic3.show();              //8+5icout<<"**************************************"<<endl;if(c1>c2)                      //调用关系运算符重载函数{cout<<"yes"<<endl;}else{cout<<"no"<<endl;}cout<<"**************************************"<<endl;Complax c4 = -c1;          //调用负号运算符重载c4.show();                  // -16 - 10icout<<"**************************************"<<endl;/*int num = 5;num++++;          //后置自增后,返回结果是一个右值++++num;          //前置自增后,返回的结果是一个左值*/Complax c5 = ++++c1;            //前置自增,先加再用c5.show();         //18+12ic1.show();         //18+12icout<<"**************************************"<<endl;Complax c6 = c1++;        //后置自增,先用再加c6.show();             //18+12ic1.show();             //19+13icout<<"**************************************"<<endl;cout<<c1 <<c2;          //cout.operator<<(c1);cout<<"**************************************"<<endl;int num = (int)c1;         //调用强制类型转换函数cout<<"num = "<<num<<endl;      //32cout<<"**************************************"<<endl;//仿函数的调用c1("hello world");cout<<"**************************************"<<endl;return 0;
}

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

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

相关文章

Python量化交易需要注意的股票交易佣金包含哪些

炒股自动化&#xff1a;申请官方API接口&#xff0c;散户也可以 python炒股自动化&#xff08;0&#xff09;&#xff0c;申请券商API接口 python炒股自动化&#xff08;1&#xff09;&#xff0c;量化交易接口区别 Python炒股自动化&#xff08;2&#xff09;&#xff1a;获取…

Web安全:SQL注入实战测试.(扫描 + 测试)

Web安全&#xff1a;SQL注入实战测试. SQL注入就是 有些恶意用户在提交查询请求的过程中 将SQL语句插入到请求内容中&#xff0c;同时程序的本身对用户输入的内容过于相信&#xff0c;没有对用户插入的SQL语句进行任何的过滤&#xff0c;从而直接被SQL语句直接被服务端执行&am…

【Python】3.基础语法(3)函数

文章目录 1.函数2.语法格式3.函数参数4. 函数返回值5. 变量作用域6.函数执行过程7. 链式调用8.嵌套调用9. 函数递归10. 参数默认值11. 关键字参数 1.函数 编程中的函数, 是一段 可以被重复使用的代码片段。 代码示例: 求数列的和, 不使用函数 # 1. 求 1 - 100 的和 sum 0 f…

“立创EDA专业版”笔记

目录 二、立创EDA专业版 2.0 整体功能 2.0.1 快捷键 2.1 右侧功能栏 2.1.1 过滤 2.2 PCB设计 2.2.1 切换亮度 2.2.2 偏移 2.2.3 单位切换 2.2.4 检查DRC 2.2.5 重新铺铜 2.2.6 布线 2.2.7 锁定 2.2.8 “过滤”设置锁定 2.3 上方菜单栏 2.3.1 保存文件 2.4 元件…

安卓(Android)平台上的MVVM架构:关键知识点、优劣分析及实践示例

​ 一、安卓MVVM架构核心知识点 1.1、架构组成 1.1.1、Model层 承载业务逻辑与数据实体&#xff0c;独立于UI并与ViewModel进行交互&#xff0c;实现数据获取与处理功能。 1.1.2、View层 负责用户界面展示&#xff0c;借助Android XML布局文件及Activity/Fragment等组件&a…

Java学习第六天

Java进阶知识面向对象 static&#xff1a;是静态的意思&#xff0c;可以修饰成员变量&#xff0c;表示该成员变量在内存中只存储一份&#xff0c;可以被共享访问。 静态成员变量&#xff08;有static修饰&#xff0c;属于类&#xff0c;内存中加载一次&#xff09;&#xff1a…

网络安全-安全渗透简介和安全渗透环境准备

文章目录 前言1. 安全渗透简介1.1 什么是安全渗透&#xff1f;1.2 安全渗透所需的工具1.3 渗透测试流程 2. 使用 Kali Linux 进行安全渗透2.1 下载ISO镜像2.2 下载VMware Workstaion软件2.3 Kali Linux简介2.4 准备Kali Linux环境2.5 Kali Linux初始配置2.6 VIM鼠标右键无法粘贴…

从汇编层看64位程序运行——likely提示编译器的优化案例和底层实现分析

大纲 代码分析with_attributes::powno_attributes::pow分析 我们在《Modern C——使用分支预测优化代码性能》一文中介绍了likely提示编译器进行编译优化&#xff0c;但是我们又讲了最终优化不是对分支顺序的调换&#xff0c;那么它到底做了什么样的优化&#xff0c;让整体性能…

Temu、Shein半托管vs全托管?养号测评怎么整?

2024年&#xff0c;跨境电商的市场风向又变了&#xff01;1月4日&#xff0c;阿里旗下的速卖通推出半托管模式&#xff0c;通过免佣金和现金补贴吸引卖家&#xff1b;同月&#xff0c;拼多多的Temu也在美国上线了半托管服务&#xff0c;TikTok Shop和SHEIN紧随其后。这给才流行…

Vue学习笔记 二

4、Vue基础扩展 4.1 插槽 组件的最大特性就是复用性,而用好插槽能大大提高组件的可复用能力在Vue中插槽是很重要的存在,通过插槽,我们可以把父组件中指定的DOM作用到子组件的任意位置,后面我们坐项目用到的组件库比如element-ui,vant-ui都频繁用到的插槽,Vue的插槽主要有…

突发性网络攻击的安全挑战分析

“网络战争对 21 世纪的意义可能就如同闪电战对 20 世纪的意义一样”, 突发性网络攻击作为 网络战争的新兴形式&#xff0c;对于世界来说仍是国家安全领域的新问题&#xff0c;对网络安全治理带来了不可忽视 的严峻挑战。 第一&#xff0c;结合当下的战略背景&#xff0c;突…

MySQL:简述多版本并发控制MVCC

一、MVCC的概念 1、MVCC 数据库并发场景有三种&#xff0c;分别为&#xff1a; &#xff08;1&#xff09;读读&#xff1a;不存在任何问题&#xff0c;也不需要并发控制。 &#xff08;2&#xff09;读写&#xff1a;有线程安全问题&#xff0c;可能会造成事务隔离性问题&am…

最新!yolov10+deepsort的目标跟踪实现

目录 yolov10介绍——实时端到端物体检测 概述 主要功能 型号 性能 方法 一致的双重任务分配&#xff0c;实现无 NMS 培训 效率-精度驱动的整体模型设计 提高效率 精度提升 实验和结果 比较 deepsort介绍&#xff1a; yolov10结合deepsort实现目标跟踪 效果展示…

小程序封装接口请求

1. 安装 wechat-http 包 npm install init -y npm install wechat-http2. 创建 `http.js` 文件 // utils/http.js import WechatHttp from wechat-http; import { handleBusinessError } from ./errorHandling; // 引入你自定义的业务错误处理函数// 初始化 WechatHttp 实例 …

.NET周刊【9月第1期 2024-09-01】

国内文章 【音视频通话】使用asp.net core 8vue3 实现高效音视频通话 https://www.cnblogs.com/1996-Chinese-Chen/p/18384394 该文章描述了使用SRS实现音视频通话和共享桌面的经验。从最初使用nginx的RTMP到研究SRS和ZLMediaKit的过程&#xff0c;再到最终实现功能的详细步…

TF | SD 卡出现无法删除的文件,乱码文件该如何处理 macOS

TF | SD 卡出现无法删除的文件&#xff0c;乱码文件该如何处理 macOS 一、问题描述 最近手头有张用在 Miyoo 掌机上的游戏 TF 卡&#xff0c;在macOS 系统下在回收站中出现了几个特殊文件名的文件&#xff0c;始终无法删除。 二、试着解决 我试过了网上的所有方法都无法删除…

RuoYi-Cloud 部署与配置 [CentOS7]

静态IP设置 # 修改网卡配置文件 vim /etc/sysconfig/network-scripts/ifcfg-ens33# 修改文件内容 TYPEEthernet PROXY_METHODnone BROWSER_ONLYno BOOTPROTOstatic IPADDR192.168.18.130 NETMASK255.255.255.0 GATEWAY192.168.18.2 DEFROUTEyes IPV4_FAILURE_FATALno IPV6INIT…

Electron桌面应用与文件路径处理:从Git、SourceTree到TortoiseGit的安装与配置

更多内容前往个人网站&#xff1a;孔乙己大叔 在开发Electron桌面应用程序时&#xff0c;正确处理文件路径是一个至关重要的环节。特别是当涉及到需要调用外部程序&#xff08;如Git、SourceTree或TortoiseGit&#xff09;时&#xff0c;确保这些程序安装在正确的位置&#xff…

@Tanstack/vue-query 的使用介绍

Tanstack/vue-query 的使用介绍 前言 在今年的vue conf 会议上&#xff0c;提到了vue-query这个库&#xff0c;这里对它的基本使用做一个介绍。 会议资料地址&#xff1a; https://vueconf.cn/ Tanstack-query的前身是react-query&#xff0c;是一个本地的服务端状态管理的库…

3.6 逻辑运算

&#x1f393; 微机原理考点专栏&#xff08;通篇免费&#xff09; 欢迎来到我的微机原理专栏&#xff01;我将帮助你在最短时间内掌握微机原理的核心内容&#xff0c;为你的考研或期末考试保驾护航。 为什么选择我的视频&#xff1f; 全程考点讲解&#xff1a;每一节视频都…