一文带你搞懂C++运算符重载

7. C++运算符重载

C++运算符重载

什么是运算符重载

  • 运算符重载赋予运算能够操作自定义类型。

  • 运算符重载前提条件: 必定存在一个自定义类型

  • 运算符重载实质: 就是函数调用

    • 友元重载

    • 类重载

  • 在同一自定义类型中,一个运算符只能被重载一次

  • C++重载只能重载已有的运算符,不能重载没有

  • C++重载一般情况不能违背运算符原来的含义(就算语法正确)

  • 注意点:

    • . ,.* ,?:,:: 不能被重载
#include <iostream>
#include <string>
using namespace std;
class MM
{
public:MM() {}MM(string name, int score) :name(name), score(score) {}
protected:string name;int score;
};
int main() 
{int a = 1;int b = 2;int sum = a + b;MM mm("小芳", 6);MM girl("小芳", 2);//error: 没有与这些操作数匹配 "xxx" 运算符//MM result = mm + girl;			//错误return 0;
}

重载写法

重载函数的写法


//函数定义方式
函数返回值类型  函数名(参数)
{//函数体;    
}
//运算符重载也是函数,只是函数名写法不同
//函数名: operator加上运算符组成函数名
//参数:
//		友元重载: 参数个数等于操作数
//		类成员函数: 参数个数等于操作-1
//		函数返回值类型:运算符组成表达式 最终结果是什么类型就返回类型
// 		int a; int b;  a+b 返回int
// 函数体:写你真正要实现的效果

友元重载

#include <iostream>
#include <string>
using namespace std;
class MM
{
public:MM() {}MM(string name, int score) :name(name), score(score) {}void print() {cout << name << "\t" << score << endl;}//友元重载friend MM operator+(MM a, MM b);		//加法重载函数的声明
protected:string name;int score;
};
MM operator+(MM a, MM b) 
{return MM(a.name, a.score+b.score);  //返回一个匿名对象
}
int main() 
{int a = 1;int b = 2;int sum = a + b;MM mm("小芳", 6);MM girl("小芳", 2);//error: 没有与这些操作数匹配 "xxx" 运算符//重载函数的隐式调用 -->mm + girl 解析为:operator+(mm, girl)MM result = mm + girl;				  //显示绿色就是运算符重载result.print();//重载函数显示调用:按照函数的调用方式MM res = operator+(mm, girl);		  //operator+:函数名  参数//string aa("12");//string bb("2323");//cout << (aa > bb) << endl;return 0;
}

类重载

#include <iostream>
#include <string>
using namespace std;
class MM
{
public:MM() {}MM(string name, int score) :name(name), score(score) {}void print() {cout << name << "\t" << score << endl;}//友元重载friend MM operator+(MM a, MM b);		//加法重载函数的声明
protected:string name;int score;
};
//类成员函数少一个参数: 对象本身可以表示参数
MM MM::operator-(MM object)
{return MM(this->name, this->score - object.score);
}int main() 
{MM mul = mm.operator-(girl);		  //类重载显示调用,跟调用普通成员函数一样的mul.print();MM girlFriend = mm - girl;			  //编译器mm - girl翻译为: mm.operator-(girl)girlFriend.print();return 0;
}

特殊运算符重载

  • 通常情况:单目运算符用类成员函数重载,双目用友元重载
  • = ,(),->,[] 只能采用成员函数重载
  • ++ --运算符重载
    • 增加一个无用参数,标识是后置++或者–
  • 流运算符重载(>> <<)
    • 输入流对象(cin): istream类
    • 输出流对象(cout): ostream类
    • 流重载必须用引用
    • 流重载一定要用友元重载
  • 后缀重载
#include <iostream>
#include <string>
#include <thread>
using namespace std;
class MM 
{
public:MM() {}MM(string name, int age) :name(name), age(age) {}void print() {cout << name << "\t" << age << endl;}//MM operator=(MM) = delete;		//删掉默认的//函数重载void operator=(int data) {this->age += data;}//++ 为例MM operator++()						//前置{this->age++;return *this;					//返回对象本身}MM operator++(int)					//后置的{return MM(this->name, this->age++);}//流运算符的重载friend ostream& operator<<(ostream& out, MM& object);friend istream& operator>>(istream& in, MM& object);private:string name;int age;
};
ostream& operator<<(ostream& out, MM& object) 
{//out当做cout用out << object.name << "\t" << object.age << endl;return out;
}
istream& operator>>(istream& in, MM& object) 
{cout << "输入对象属性:";//in当做cin用即可in >> object.name >> object.age;return in;
}
//文本重载, 一般写成下划线系列
//后缀的重载
unsigned long long operator""_h(unsigned long long data) 
{return data * 60 * 60;
}
unsigned long long operator""_m(unsigned long long data)
{return data * 60;
}
unsigned long long operator""_s(unsigned long long data)
{return data;
}
int main() 
{MM mm("小芳", 18);MM girl;girl = mm;				//每一个类中都存在默认的赋值重载girl = 8;girl.print();MM result = ++girl;result.print();girl.print();result = girl++;result.print();girl.print();cin >> girl;cout << girl << endl;	//this_thread::sleep_for(10s);cout << 1_h << endl;cout << (1_h + 30_m + 49_s) << endl;return 0;
}

对象的隐式转换

对象隐式转换: 就是让对象能够赋值给普通数据

//operator  转换的类型()
//{ 
//	return 要转换类型的数据;
//}
#include <string>
#include <iostream>
using namespace std;
class MM 
{
public:MM() {}MM(string name, int age) :name(name), age(age) {}operator int() {return this->age;}
protected:string name;int age;
};
int main() 
{MM mm("mm", 39);int age = mm;cout << age << endl;return 0;
}

()运算符的重载

仿函数

让类型可以模仿函数调用的行为: 函数名(参数); 类名() 调用的函数行为

#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;class Data 
{
public://operator()组成函数名void operator()() {cout << "无参重载()" << endl;}void operator()(int a, int b) {cout << "有参重载(a,b)" << endl;}
protected:};
int main() 
{//greater<int>();  //比较准则//int array[5] = { 3,4,1,2,32 };//sort(array, array + 5, greater<int>());//for (auto& v : array) //{//	cout << v << "\t";//}//cout << endl;Data data;data.operator()();		//显式调用data.operator()(1, 2);	//显式调用data();					//隐式调用data(1, 2);				//隐式调用Data{}();				//{}帮助识别  Data()Data{}(2, 3);return 0;
}

运算符重载案例分析

智能指针

智能指针是用对象方式管理new的内存,可以做到自动释放(本质是析构函数自动调用)内存的功能

#include <iostream>
#include <memory>
using namespace std;
class Auto_Ptr 
{
public:Auto_Ptr(int* ptr) :ptr(ptr) {}~Auto_Ptr() {if (ptr) {delete ptr;ptr = nullptr;}}//访问指针int* operator->() {return this->ptr;}//访问数据int& operator*() {return *ptr;}//禁止拷贝,禁止赋值Auto_Ptr(Auto_Ptr&) = delete;Auto_Ptr& operator=(Auto_Ptr&) = delete;
protected:int* ptr;
};
int main() 
{Auto_Ptr object(new int(1999));cout << *object << endl;//shared_ptr<int>  p(new int(19999));//cout << *p << endl;//shared_ptr<double>  p2(new double(19.99));//cout << *p2 << endl;return 0;
}

封装数组

#include <iostream>
#include <vector>			//动态数组
using namespace std;
class my_vector 
{
public:my_vector(int capacity = 10) :capacity(capacity) {mem = new int[capacity] {0};curSize = 0;}void push_back(int data) {mem[curSize++] = data;}int* begin() {return mem + 0;}int* end() {return mem + capacity;}int& operator[](int index) {if (curSize < index)curSize = index;return mem[index];}//万金油函数int size() {return curSize;}int empty() {return curSize == 0;}~my_vector() {if (mem) {delete[] mem;mem = nullptr;}}
protected:int* mem;int capacity;int curSize;
};int main() 
{my_vector vec;for (int i = 0; i < 3; i++) {vec[i] = i;}for (auto v : vec) {cout << v << "\t";}cout << endl;cout << vec.size() << endl;for (int i = 0; i < vec.size(); i++) {cout << vec[i] << "\t";}cout << endl;return 0;
}

迭代器实现

//迭代器就是让一个类中类去遍历数据

#include <iostream>
#include <string>
using namespace std;
struct Node 
{int data;Node* next;Node() :next(nullptr){}Node(int data) :data(data), next(nullptr) {}Node(int data, Node* next) :data(data), next(next) {}
};
class List 
{
public:List() :headNode(new Node),curSize(0){}void push_front(int data) {headNode->next = new Node(data, headNode->next);curSize++;}Node* begin() {return headNode->next;}Node* end() {return nullptr;}class iterator {public:iterator() :pmove(nullptr) {}void operator=(Node* pmove) {this->pmove = pmove;}bool operator!=(Node* pmove) {return this->pmove != pmove;}iterator operator++() {this->pmove = this->pmove->next;	//链表++不了return *this;}int operator*() {return this->pmove->data;			//*运算访问数据}private:Node* pmove;			//需要指针访问数据};protected:Node* headNode;int curSize;
};
void my_list() 
{List list;for (int i = 0; i < 3; i++) {list.push_front(i);}List::iterator it;for (it = list.begin(); it != list.end(); ++it){cout << *it << " ";}cout << endl;
}
int main() 
{string str = "ILoveyou";for (int i = 0; i < str.size(); i++) {cout << str[i];}cout << endl;//类中类访问一个容器数据string::iterator it;for (it = str.begin(); it != str.end(); it++) {cout << *it;		//*指针取值运算}cout << endl;//cout << *str.end() << endl;my_list();return 0;
}

重载的特殊问题

//对象与常量运算
#include <iostream>
#include <string>
using namespace std;
class Data 
{
public:Data() {}Data(int num) :num(num) {}//friend Data operator+(Data data, int num);//friend Data operator+( int num, Data data);//Data operator+(Data data) //{//	return Data(this->num + data.num);//}void print() {cout << num << endl;}friend Data operator+(Data data1, Data data2);
protected:int num;
};
//Data operator+(Data data, int num) 
//{
//	return Data(data.num + num);
//}
//Data operator+(int num, Data data) 
//{
//	return Data(num + data.num);
//}
Data operator+(Data data1, Data data2) 
{return Data(data1.num + data2.num);
}
int main() 
{Data data(1);Data temp;//data.成员函数(1);temp = data + 1;//1+data : 1.成员函数()temp = 1 + data;   //类成员函数没办法完成temp.print();return 0;
}

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

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

相关文章

vue element-ui日期控件传参

前端&#xff1a;Vue element-ui <el-form-item label"过期时间" :rules"[ { required: true, message: 请选择过期时间, trigger: blur }]"><el-date-picker v-model"form.expireTime" type"date" format"yyyy-MM-dd&…

【C++】透析类和对象(下)

有不懂的可以翻阅我之前文章&#xff01; 个人主页&#xff1a;CSDN_小八哥向前冲 所属专栏&#xff1a;CSDN_C入门 目录 拷贝构造函数 运算符重载 赋值运算符重载 取地址运算符重载 const成员函数 取地址重载 再探构造函数 初始化列表 类型转换 static成员 友元 内…

MySQL查询执行(二):order by工作原理

假设你要查询城市是“杭州”的所有人名字&#xff0c; 并且按照姓名排序返回前1000个人的姓名、 年龄。 假设这个表的部分定义是这样的&#xff1a; -- 创建表t CREATE TABLE t (id int(11) NOT NULL,city varchar(16) NOT NULL,name varchar(16) NOT NULL,age int(11) NOT N…

Docker 搭建Elasticsearch详细步骤

本章教程使用Docker搭建Elasticsearch环境。 一、拉取镜像 docker pull docker.elastic.co/elasticsearch/elasticsearch:8.8.2二、运行容器 docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-n

maven clean报错:Failed to delete xxxxx\target\xxxx.jar

问题描述 今天使用maven的clean命令时候出错如下&#xff1a; 分析问题 target文件可能时编译的文件被其他程序占用&#xff0c;导致资源无法回收 解决问题 1 打开任务管理器 右键任务栏。进入任务管理器 点击详细信息 2 进入 点击性能&#xff0c;点击打开资源监视器 …

推荐2024年大家都在用的4款ai写作免费神器

最近公司年中总结&#xff0c;要写好多像工作报告&#xff0c;工作计划之类的文件。我尝试着使用AI写作工具帮助&#xff0c;没想到效果意外的好&#xff0c;省事又省力。如果你也有和我一样的烦恼的话&#xff0c;可以去使用这4个写作工具&#xff0c;都是可以免费使用的。 1、…

错误代码0x80070035是什么情况?针对错误代码0x80070035的解决方法

错误代码 0x80070035 通常与网络连接和文件共享有关&#xff0c;表示“找不到网络路径”。这个问题可能由多种原因引起&#xff0c;包括网络设置不当、服务未启动、注册表配置错误等。今天这篇文章就和大家分享几种针对错误代码0x80070035的解决方法。 针对错误代码0x80070035问…

express连接mysql

一、 安装express npm install express --save二、express配置 //引入 const express require("express"); //创建实例 const app express(); //启动服务 app.listen(8081, () > {console.log("http://localhost:8081"); });三、安装mysql npm i m…

简过网:大学生考公,一定要先好好看看这篇文章!

大家好&#xff0c;我是简过网&#xff0c;今天这篇文章我们来聊聊关于大学生考公的那些事儿&#xff0c;希望能给大学生们一点点的帮助&#xff01; 首先&#xff0c;可能有朋友会问了&#xff0c;大学生一般从什么时候开始备考公务员呢&#xff0c;在这里小编建议大家从大三…

mysql1055报错解决方法

目录 一、mysql版本 二、 问题描述 三、解决方法 1.方法一&#xff08;临时&#xff09; 2.方法二&#xff08;永久&#xff09; 一、mysql版本 mysql版本&#xff1a;5.7.23 二、 问题描述 在查询时使用group by语句&#xff0c;出现错误代码&#xff1a;1055&#xf…

FastAPI(七十四)实战开发《在线课程学习系统》接口开发-- 删除留言

源码见&#xff1a;"fastapi_study_road-learning_system_online_courses: fastapi框架实战之--在线课程学习系统" 之前文章FastAPI&#xff08;七十三&#xff09;实战开发《在线课程学习系统》接口开发-- 回复留言&#xff0c;那么我们这次分享删除留言接口的开发…

MySQL可重复读的隔离机制下是否彻底解决了幻读?

答案&#xff1a;没有彻底解决。 一、什么是幻读&#xff1f; 当同一个查询在不同时间产生不同的结果集时&#xff0c;事务中就会出现幻读问题。 幻读关注的是记录数量的不同。 不可重复读关注的是记录内容的不同。 二、快照读和当前读 InnoDB引擎的默认隔离级别是可重复读&…

搭建自己的金融数据源和量化分析平台(四):自动化更新上市公司所属一级、二级行业以及股票上市状态

前面做了更新沪深交易所的上市股票列表的读取和更新&#xff0c;但一旦股票退市则需要在数据库里将该股票状态更新为退市&#xff0c;同时附上退市日期&#xff0c;将股票名更改为XX退。 此外深交所下载的xls解析出来是没有上市公司所属的二级行业的&#xff0c;因此还需要建立…

鸿蒙仓颉语言之【安全密码库crypto4cj】功能示例

功能示例 MD5使用样例 from crypto4cj import md5cj.*main() { var md: Array<UInt8> Array<UInt8>(16, item: 0)var result: String String(Array<Char>(33, item: 0))var str: String "helloworld"var ret md5(str.toUtf8Array(), md)r…

不支持jdk8的jenkins部署jdk8项目

1、背景 目前最新的jenkins必须基于jdk8以上&#xff0c;才能安装。jenkins最新的插件部分也不支持jdk8了。 2、全局工具配置 配置一个jdk8 配置一个jdk8以上的版本&#xff0c;如jdk17 3、部署maven项目 jdk17项目 可以直接使用maven插件&#xff0c;部署。 jdk8项目 由…

git等常用工具以及cmake

一、将git中的代码克隆进电脑以及常用工具介绍 1.安装git 首先需要安装git sudo apt install git 注意一定要加--recursive&#xff0c;因为文件中有很多“引用文件“&#xff0c;即第三方文件&#xff08;库&#xff09;&#xff0c;加入该选项会将文件中包含的子模…

C嘎嘎浅谈模板

这篇文章给大家介绍一下c嘎嘎内存管理和模板&#xff0c;那么我们直接进入正题 c/c的程序内存分布 这里的了解一下即可 new和delete的定义和操作 格式&#xff1a;类型* 对象名 new 类型&#xff1b; 数组(对象)定义格式&#xff1a;类型* 对象名 new 类型[元素个数]&…

NOIP图论 最小生成树——Prim算法(详细图解)

最小生成树的概念 经典题目 prim算法简介 prim算法解析 &#xff08;详细图解&#xff09; 代码实现 代码实战 最小生成树的概念 在一给定的无向图G (V, E) 中&#xff0c;(u, v) 代表连接顶点 u 与顶点 v 的边&#xff0c;而 w(u, v) 代表此的边权重&#xff0c;若存在 …

Kali中docker与docker-compose的配置

权限升级 sudo su 升级为root用户 更新软件 apt-get update安装HTTPS协议和CA证书 apt-get install -y apt-transport-https ca-certificates下载docker apt下载docker apt install docker.io 验证docker安装是否成功 查版本 docker -v 启动docker systemctl start …

QT自定义无边框窗口(可移动控制和窗口大小调整)

QT是一个功能强大的跨平台开发框架&#xff0c;它提供了丰富的界面设计工具和组件。在界面开发中&#xff0c;QT窗口自带的标题栏无法满足我们的需求。我们就需要自定义无边框窗口&#xff0c;包括自定义标题栏和窗口大小调整功能。本文将介绍如何在QT中实现这些功能。 一、简…