一文带你搞懂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://xiahunao.cn/news/3269334.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

2024年国际高校数学建模竞赛问题B:空间迁移计划和战略 成品文章分享

2024年国际高校数学建模竞赛问题B&#xff1a;空间迁移计划和战略&#xff08;2024 International Mathematics Molding Contest for Higher Education (IMMCHE)Problem B: Space Migration Program and Strategy&#xff09; 星际迁移计划中的资源分配与风险管理策略研究 摘…

【计算机网络】数据链路层实验

一&#xff1a;实验目的 1&#xff1a;学习WireShark软件的抓包操作&#xff0c;分析捕获的以太网的MAC帧结构。 2&#xff1a;学习网络中交换机互相连接、交换机连接计算机的拓扑结构&#xff0c;理解虚拟局域网&#xff08;WLAN&#xff09;的通信机制。 3&#xff1a;学习…

什么材质的挖耳勺好用?硬核上佳产品分享!

耳道健康随着生活品质的提高&#xff0c;逐渐被大家重视。因为它会直接影响我们的听力和卫生健康&#xff0c;如果长时间不清理&#xff0c;很容易堵塞在耳膜里导致耳鸣头晕等状况。挖耳勺的材质非常多&#xff0c;有铁质、不锈钢、软硅胶等等&#xff0c;那么什么材质的挖耳勺…

2024年国际高校数学建模竞赛问题B:空间迁移计划和战略完整思路 模型 代码 结果分享(仅供学习)

2024年国际高校数学建模竞赛问题B&#xff1a;空间迁移计划和战略&#xff08;2024 International Mathematics Molding Contest for Higher Education (IMMCHE)Problem B: Space Migration Program and Strategy&#xff09; 我们的未来有两种可能性:第一&#xff0c;我们将留…

国科大作业考试资料《人工智能原理与算法》2024新编-第十三次作业整理

1、假设我们从决策树生成了一个训练集&#xff0c;然后将决策树学习应用于该训练集。当训练集的大小趋于无穷时&#xff0c;学习算法将最终返回正确的决策树吗&#xff1f;为什么是或不是&#xff1f; 本次有两个参考&#xff1a; 参考一&#xff1a; 当训练集的大小趋于无穷…

飞牛爬虫FlyBullSpider 一款简单方便强大的爬虫,限时免费 特别适合小白!用它爬下Boss的2024年7月底Java岗位,分析一下程序员就业市场行情

一、下载安装FlyBullSpider 暂时支持Window,现在只在Win11上做过测试 1 百度 点击百度网盘 下载 链接&#xff1a;https://pan.baidu.com/s/1gSLKYuezaZgd8iqrXhk8Kg 提取码&#xff1a;Fly6 2 csdn https://download.csdn.net/download/fencer911/89584687 二、体验初…

C++(入门1)

C参考文档 Reference - C Reference C 参考手册 - cppreference.com cppreference.com 第一个C程序 #include<stdio.h> int main() {printf("Hello C\n");return 0; }由上述代码可知C是兼容C语言 第一个C标准程序 #include<iostream> using names…

Python教程(一):环境搭建及PyCharm安装

目录 引言1. Python简介1.1 编译型语言 VS 解释型语言 2. Python的独特之处3. Python应用全览4. Python版本及区别5. 环境搭建5.1 安装Python&#xff1a; 6. 开发工具&#xff08;IDE&#xff09;6.1 PyCharm安装教程6.2 永久使用教程 7. 编写第一个Hello World结语 引言 在当…

NO.1 Hadoop概述

目录 1.1 Hadoop是什么​编辑 1.2 Hadoop优势​编辑​编辑 1.3 Hadoop组成​编辑 1.3.1 HDFS架构概述 ​编辑 1.3.2 YARN架构概述 ​编辑 1.3.3 MapReduce架构概述​编辑 1.3.4 HDFS、YARN、MapReduce三者关系 1.4 大数据技术生态体系 1.5 推荐系统框架图 1.1 Hadoop…

Prometheus各类监控及监控指标和告警规则

目录 linux docker监控 linux 系统进程监控 linux 系统os监控 windows 系统os监控 配置文件&告警规则 Prometheus配置文件 node_alert.rules docker_container.rules mysql_alert.rules vmware.rules Alertmanager告警规则 consoul注册服务 Dashboard JSON…

ARM32开发——PWM蜂鸣器案例

&#x1f3ac; 秋野酱&#xff1a;《个人主页》 &#x1f525; 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 需求原来的驱动移植操作替换初始化 更新Play函数完整代码 需求 通过控制PB9来播放音乐&#xff0c;PB9对应的定时器通道&#xff1…

Web3 职场新手指南:从技能到素养,求职者如何脱颖而出?

随着 2024 年步入下半年&#xff0c;Web3 行业正在经历一系列技术革新。通过改进的跨链交互机制和兼容性&#xff0c;逐步消除市场碎片化的问题。技术的进步为开发者和用户都打开了新的前景。然而&#xff0c;复杂的技术和快速变化的市场环境也让许多新人望而却步。求职者如何找…

【数据结构】双向带头循环链表(c语言)(附源码)

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;数据结构 目录 前言 1.双向带头循环链表的概念和结构定义 2.双向带头循环链表的实现 2.1 方法声明 2.2 方法实现 2.2.1 创建新节点 2.2.2 初始化 2.2.3 …

【基于yolo转onnx 量化测试】

1、 训练模型转onnx 和量化 from ultralytics import YOLOmodel_path "yolov10/runs/train8/weights/best.pt" model YOLO(model_path) # 载入官方模型 # 导出模型 model.export(formatonnx,halfTrue)2、量化&#xff0c;减少了三分之一的存储空间从100M到30M …

当镜像地址出错的时候下载selenium的处理办法

当镜像地址出错的时候下载selenium的处理办法 一、原因 显示出错&#xff1a; C:\Users\xiaodaidai>pip install selenium3.4.0 Looking in indexes: Simple Index WARNING: Retrying (Retry(total4, connectNone, readNone, redirectNone, statusNone)) after connection …

学语言,看这里,如何快速掌握JavaScript?

本篇文章是基于会点c语言和会点python基础的&#xff0c;去更容易上手javascript 学习笔记分享✨&#x1f308;&#x1f44f;&#x1f44f;&#x1f451;&#x1f451; javascript目录 1.安装node.js&#xff1a;2.配置环境变量——创建NODE_HOME :3.变量与常量4.原生数据类型5…

C++ —— STL简介

1. 什么是STL STL(standard template libaray-标准模板库)&#xff1a;是C标准库的重要组成部分&#xff0c;不仅是一个可复用的 组件库&#xff0c;而且是一个包罗数据结构与算法的软件框架 2.STL的版本 原始版本 Alexander Stepanov、Meng Lee 在惠普实验室完成的原始版本…

Java之父官宣退休

今年不用说大家都知道环境真的很差很差&#xff0c;裁员降薪已经是家常便饭&#xff0c;在这种严峻环境下&#xff0c;我们只能提升自己内功来抗风险&#xff0c;下面分享一本java之父推荐的优秀书籍。 刚过完自己 69 岁生日的两个月后&#xff0c;Java 之父 James Gosling&…

论文阅读:Deep_Generic_Dynamic_Object_Detection_Based_on_Dynamic_Grid_Maps

目录 概要 Motivation 整体框架流程 技术细节 小结 不足 论文地址&#xff1a;Deep Generic Dynamic Object Detection Based on Dynamic Grid Maps | IEEE Conference Publication | IEEE Xplore 概要 该文章提出了一种基于动态网格图&#xff08;Dynamic Grid Maps&a…

Golang高效合并(拼接)多个gzip压缩文件

有时我们可能会遇到需要把多个 gzip 文件合并成单个 gzip 文件的场景&#xff0c;最简单最容易的方式是把每个gzip文件都先解压&#xff0c;然后合并成一个文件后再次进行压缩&#xff0c;最终得到我们想要的结果&#xff0c;但这种先解压后压缩的方式显然效率不高&#xff0c;…