C++ 运算符重载 (备查)

基础

运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型

运算符重载也可以发生函数重载

语法:

void operator@();	//@代表了被重载的运算符。函数的参数个数取决于两个因素。1)运算符是一元(一个参数)的还是二元(两个参数)2)运算符被定义为全局函数(对于一元是一个参数,对于二元是两个参数)还是成员函数(对于一元没有参数,对于二元是一个参数-此时该类的对象用作左耳参数)
成员函数重载 + 全局函数重载 原理

在这里插入图片描述

运算符重载(operator overloading)只是一种”语法上的方便”,也就是它只是另一种函数调用的方式。

是否可重载

在这里插入图片描述

几乎C中所有的运算符都可以重载,但运算符重载的使用时相当受限制的。

不能改变运算符优先级,不能改变运算符的参数个数。

加号(+)运算符重载

//利用成员函数实现加号运算符重载
Person operator+(Person &p)
{Person temp;temp.m_A = this->m_A + p.m_A;temp.m_B = this->m_B + p.m_B;return temp;
}private:int m_A;int m_B;
//利用全局函数实现加号运算符重载
Person operator+(Person &p1, Person &p2)
{Person temp;temp.m_A = p1.m_A + p2.m_A;temp.m_B = p1.m_B + p2.m_B;return temp;
}

重载左移操作符(<<),使得 cout 可以输出自定义对象

为什么不用 成员函数重载 实现

在这里插入图片描述

使用 全局函数 重载 << 运算符(无法链式编程)

在这里插入图片描述

cout 是 ostream 类的对象,全局只有一个,所以使用 & 。

要实现 cout 链式输出需返回 cout 引用

在这里插入图片描述

如果要访问类中私有属性,配合友元实现
//重载 << 运算符案列
class Person{friend ostream& operator<<(ostream& os, Person& person);//友元
public:Person(int id,int age){mID = id;mAge = age;}
private:int mID;int mAge;
};//重载 <<  运算符
ostream& operator<<(ostream& os, Person& person){os << "ID:" << person.mID << " Age:" << person.mAge;return os;
}int main(){Person person(1001, 30);//cout << person; //cout.operator+(person)cout << person << " | " << endl;return EXIT_SUCCESS;
}

自增自减(++/–)运算符重载

class Complex{public:Complex(){mA = 0;mB = 0;}//重载前置++Complex& operator++(){mA++;mB++;return *this;	//返回的的是引用,可以实现链式编程:(++(++b))}//重载后置++Complex operator++(int){	Complex temp;temp.mA = this->mA;temp.mB = this->mB;mA++;mB++;return temp;	//temp是局部对象,不能返回引用,所以不能实现链式编程。}//前置--Complex& operator--(){mA--;mB--;return *this;}//后置--Complex operator--(int){Complex temp;temp.mA = mA;temp.mB = mB;mA--;mB--;return temp;}private:int mA;int mB;
};

如何区分重载的前置++还是后置++,通过占位参数来区分,有 int 的为后置++,- - 同理。

要优先使用前缀形式,由于前缀形式创建了一个临时对象,效率经常会略高一些。

指针运算符( *、-> )重载

利用智能指针,管理 new 出来的 Person 的释放操作。

//被维护的类
class Person{
public:Person(int param){this->mParam = param;}void PrintPerson(){cout << "Param:" << mParam << endl;}
private:int mParam;
};//智能指针
class SmartPointer{
public:SmartPointer(Person* person){this->pPerson = person;}//重载指针的 -> 操作符Person* operator->(){return pPerson;}//重载指针的 * 操作符Person& operator*(){return *pPerson;}~SmartPointer(){if (pPerson != NULL){delete pPerson;	//在析构中释放 被维护对象空间this.pPerson = NULL;}}
public:Person* pPerson;	//维护一个被管理类的指针
};void test01(){SmartPointer pointer(new Person(18));	//通过构造,实例化被被维护的对象//本质:pointer->->PrintPerson(); 编译器简化为:pointer->PrintPerson();pointer->PrintPerson();	(*pointer).PrintPerson();
}

智能指针类 执行在栈上,执行完后自动释放,同时也释放了被维护对象的空间。

自动释放体现出:智能
指针运算符( * ,-> )重载体现出: 指针

赋值(=)运算符重载

编译器 默认给一个类提供四个函数:默认构造,拷贝构造(浅拷贝),析构函数 ,operator= (浅拷贝)。

在这里插入图片描述

//赋值(=)运算符重载-------详细案列
class Person{friend ostream& operator<<(ostream& os,const Person& person){os << "ID:" << person.mID << " Age:" << person.mAge << endl;return os;}
public:Person(int id,int age){this->mID = id;this->mAge = age;}//重载赋值运算符Person& operator=(const Person& person){this->mID = person.mID;this->mAge = person.mAge;return *this;}
private:int mID;int mAge;
};//1. =号混淆的地方
void test01(){Person person1(10, 20);Person person2 = person1; //调用拷贝构造//如果一个对象还没有被创建,则必须初始化,也就是调用构造函数//上述例子由于person2还没有初始化,所以会调用构造函数//由于person2是从已有的person1来创建的,所以只有一个选择//就是调用拷贝构造函数person2 = person1; //调用operator=函数//由于person2已经创建,不需要再调用构造函数,这时候调用的是重载的赋值运算符
}
//2. 赋值重载案例
void test02(){Person person1(20, 20);Person person2(30, 30);cout << "person1:" << person1;cout << "person2:" << person2;person2 = person1;cout << "person2:" << person2;
}
//常见错误,当准备给两个相同对象赋值时,应该首先检查一下这个对象是否对自身赋值了
//对于本例来讲,无论如何执行这些赋值运算都是无害的,但如果对类的实现进行修改,那么将会出现差异;
//3. 类中指针
class Person2{friend ostream& operator<<(ostream& os, const Person2& person){os << "Name:" << person.pName << " ID:" << person.mID << " Age:" << person.mAge << endl;return os;}
public:Person2(char* name,int id, int age){this->pName = new char[strlen(name) + 1];strcpy(this->pName, name);this->mID = id;this->mAge = age;}
#if 1//重载赋值运算符Person2& operator=(const Person2& person){//注意:由于当前对象已经创建完毕,那么就有可能pName指向堆内存//这个时候如果直接赋值,会导致内存没有及时释放if (this->pName != NULL){delete[] this->pName;}this->pName = new char[strlen(person.pName) + 1];strcpy(this->pName,person.pName);this->mID = person.mID;this->mAge = person.mAge;return *this;}
#endif//析构函数~Person2(){if (this->pName != NULL){delete[] this->pName;}}
private:char* pName;int mID;int mAge;
};void test03(){Person2 person1("John",20, 20);Person2 person2("Edward",30, 30);cout << "person1:" << person1;cout << "person2:" << person2;person2 = person1;cout << "person2:" << person2;
}

等于和不等于(==、!=)运算符重载

class Complex{
public:Complex(char* name,int id,int age){this->pName = new char[strlen(name) + 1];strcpy(this->pName, name);this->mID = id;this->mAge = age;}//重载==号操作符bool operator==(const Complex& complex){if (strcmp(this->pName,complex.pName) == 0 && this->mID == complex.mID && this->mAge == complex.mAge){return true;}return false;}//重载!=操作符bool operator!=(const Complex& complex){if (strcmp(this->pName, complex.pName) != 0 || this->mID != complex.mID || this->mAge != complex.mAge){return true;}return false;}~Complex(){if (this->pName != NULL){delete[] this->pName;}}
private:char* pName;int mID;int mAge;
};
void test(){Complex complex1("aaa", 10, 20);Complex complex2("bbb", 10, 20);if (complex1 == complex2){ cout << "相等!" << endl; }if (complex1 != complex2){ cout << "不相等!" << endl; }
}

函数调用符号()重载

class Complex{
public:int Add(int x,int y){return x + y;}int operator()(int x,int y){return x + y;}
};
void test01(){Complex complex;cout << complex.Add(10,20) << endl;//对象当做函数来调用cout << complex(10, 20) << endl;
}

不要重载&&、||

不能重载 operator&& 和 operator|| 的原因是,无法在这两种情况下实现内置操作符的完整语义。(即:不能实现短路特性

符号重载建议

在这里插入图片描述

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

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

相关文章

数据结构和算法-图的基本操作以图的广度优先遍历和深度优先遍历

文章目录 图的基本操作总览找边列出与某顶点相连的边插入顶点删除顶点增加边顶点的第一个邻接点顶点的下一个邻接点设置或者获取某条边的权值总览 图的广度优先遍历总览树的广度优先遍历图的广度优先遍历树vs图图广度优先遍历的代码实现广度优先遍历序列遍历序列的可变性算法存…

深眸科技|轻辙视觉引擎以99.9%视觉检测能力为基准,赋能木材加工

轻辙视觉引擎&#xff1a;轻辙视觉引擎是以低代码为基础&#xff0c;深度学习技术为核心的视觉业务流程编排引擎&#xff0c;用于快速搭建部署复杂视觉检测流程软件方案。 轻辙视觉引擎&#xff5c;轻量级产品实现高效应用 作为深眸科技的核心产品之一&#xff0c;轻辙视觉引…

十进制整数转二进制数

十进制整数转二进制数 % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 函 数 名&#xff1a;dec_2_bin % 功 能&#xff1a;十进制整数转二进制数 % 输入参数&#xff1a; % % 1.参数dec&#xff1a;十进制数 % % 2.参数width&#xff1a;用多少位宽表示二进制…

论文润色突显研究亮点 papergpt

大家好&#xff0c;今天来聊聊论文润色突显研究亮点&#xff0c;希望能给大家提供一点参考。 以下是针对论文重复率高的情况&#xff0c;提供一些修改建议和技巧&#xff1a; 标题&#xff1a;论文润色突显研究亮点――提升论文吸引力的关键步骤 一、引言 在学术研究中&#x…

【算法刷题】Day15

文章目录 1. 串联所有单词的子串题干&#xff1a;算法原理代码&#xff1a; 2. 最小覆盖子串题干&#xff1a;算法原理&#xff1a;1、暴力枚举 哈希表2、滑动窗口 哈希表 代码&#xff1a; 1. 串联所有单词的子串 原题链接 题干&#xff1a; 给定⼀个字符串 s 和⼀个字符串…

Vue项目使用WebAssembly之后,Nginx如何解决WebAssembly不支持的问题

在VUE项目中使用WebAssembly之后&#xff0c;打包的项目会出现下面的错误 Uncaught (in promise) TypeError: WebAssembly: Response has unsupported MIME type application/wasm; charsetutf-8 expected application/wasm 可以用以下办法解决 一&#xff1a;单独Nginx配置…

选择排序-排序算法

思路 选择排序&#xff08;Selection sort&#xff09;的主要思路是&#xff1a;在要排序的区间内找到一个最大的元素&#xff0c;将它放到数组的最后一个位置&#xff0c;然后在剩余的未排序区间内找到一个最大的元素&#xff0c;将它放到数组的倒数第二个位置。以此类推&…

基于 Flink CDC 构建 MySQL 的 Streaming ETL to MySQL

简介 CDC 的全称是 Change Data Capture &#xff0c;在广义的概念上&#xff0c;只要是能捕获数据变更的技术&#xff0c;我们都可以称之为 CDC 。目前通常描述的 CDC 技术主要面向数据库的变更&#xff0c;是一种用于捕获数据库中数据变更的技术。CDC 技术的应用场景非常广泛…

抖捧自动直播是什么,系统功能讲解

目前有在做实体行业级商家服务的老板 你还在为不会直播&#xff0c;不敢直播而苦恼吗&#xff1f; 你还在为想做直播&#xff0c;但没空开直播而焦灼吗&#xff1f; 今天&#xff0c;你的问题都可以统统解决 实体行业直播必备黑科技&#xff1a;抖捧AI自动直播 只需要一部手…

【vue】element el-table怎么实现跨页勾选

【vue】element el-table怎么实现跨页勾选 需求 由后端提供分页接口&#xff0c;每一次翻页el-table的数据都会被刷新一次&#xff0c;这种情况下怎么实现跨页的勾选 代码 <el-tableref"multipleTable"v-loading"loading":data"operationList&…

使用阿里巴巴同步工具DataX实现Mysql与ElasticSearch数据同步

一、Linux环境要求 二、准备工作 2.1 Linux安装jdk 2.2 linux安装python 2.3 下载DataX&#xff1a; 三、DataX压缩包导入&#xff0c;解压缩 四、编写同步Job 五、执行Job 六、定时更新 6.1 创建定时任务 6.2 提交定时任务 6.3 查看定时任务 七、增量更新思路 一、Linux环境要…

C#教程(一):面向对象

1、介绍 C#是一种多范式编程语言&#xff0c;但其中一个主要的编程范式是面向对象编程&#xff08;OOP&#xff09;。面向对象编程有一些特点&#xff0c;而C#提供了丰富的功能来支持这些特点。 2、面向对象特点 封装&#xff08;Encapsulation&#xff09;&#xff1a; 封装…

亚马逊云科技产品测评榜单新鲜出炉,你上榜了吗?

随着云计算时代的到来&#xff0c;高新科技产品成为我们生活中不可或缺的东西&#xff0c;亚马逊云科技产品全面发力以创新技术助力每一个用户。感受和测评最热门的亚马逊云科技开发者工具与服务为技术发展提供了更多的可能性。 亚马逊云科技产品测评中&#xff0c;大家借助亚马…

微信小程序--判断目标元素是否在可视区域内(可视区域播放视频)

步骤&#xff1a; 1、创建对象实例 2、获取/指定界面上的节点信息 3、判断节点是否在当前屏幕可视区域 微信API提供了两种获取创建对象实例和获取节点的方法&#xff0c;按照以上步骤&#xff0c;我们一一来看&#xff1a; 1、wx.createSelectorQuery() wx.createSelectorQ…

Nginx访问FTP服务器文件的时效性/安全校验

背景 FTP文件服务器在我们日常开发中经常使用&#xff0c;在项目中我们经常把FTP文件下载到内存中&#xff0c;然后转为base64给前端进行展示。如果excel中也需要导出图片&#xff0c;数据量大的情况下会直接返回一个后端的开放接口地址&#xff0c;然后在项目中对接口的参数进…

使用shell脚本将一台虚拟机上面数据分发到其他虚拟机上面xsync

目录 1&#xff0c;功能2&#xff0c;注意点3&#xff0c;shell脚本介绍4&#xff0c;bash内容 1&#xff0c;功能 使用shell脚本将一台虚拟机上面数据分发到其他虚拟机上面。 2&#xff0c;注意点 需要修改的地方&#xff1a;hadoop250 hadoop251 hadoop252 hadoop253 hado…

魔搭社区上线Mistral AI 首个开源 MoE 模型 Mixtral8x7B

Mistral AI 近日发布了首个开源 MoE 模型 Mixtral8x7B&#xff0c;并宣布在魔搭社区上线。 Mixtral-8x7B 是一款混合专家模型&#xff08;Mixtrue of Experts&#xff09;&#xff0c;由8个拥有70亿参数的专家网络组成&#xff0c;在能力上&#xff0c;Mixtral-8x7B 支持32k t…

Java的引用类型有几种?区别是什么?

Java中的引用类型主要分为四种&#xff1a;强引用&#xff08;Strong Reference&#xff09;、软引用&#xff08;Soft Reference&#xff09;、弱引用&#xff08;Weak Reference&#xff09;和虚引用&#xff08;Phantom Reference&#xff09;。这些引用类型在Java中主要用于…

MyBatis-Flex 常见问题

文章目录 官网常见问题MyBatis-Flex 没有启动或者启动出错怎么办&#xff1f;示例中的 AccountMapper 和 "ACCOUNT" 在哪里&#xff0c;报错了。阿里镜像找不到依赖&#xff1f;SpringBoot 3.2 项目&#xff0c;启动报错 Invalid value type for attribute factoryBe…

【Qt5】QMouseEvent的globalPos

2023年12月14日&#xff0c;周四下午 QMouseEvent的globalPos()函数是用于获取鼠标事件发生时的全局坐标。它返回一个QPoint对象&#xff0c;表示鼠标事件的全局位置。 全局坐标是相对于整个屏幕的坐标系&#xff0c;而不是相对于应用程序窗口或控件的坐标系。它可以用来确定鼠…