【C++】揭开运算符重载的神秘面纱
目录
一、引言
优点
二、介绍
1.定义
2.语法
三、示例
1.加法运算符重载
2.一元运算符重载
3.友元函数
4.流插入和流提取
5.自增自减运算符
总结
一、引言
何为运算符重载?运算符重载,是C++中的一项强大特性,赋予了程序员在自定义类型上实现更直观、灵活的操作的能力。通过运算符重载,我们可以为自定义的类或结构体定义标准运算符的行为,使得代码更加富有表达力,更接近自然语言的阐述方式。下面我们来具体谈谈运算符重载的有关知识,揭开她的神秘面纱。
优点
在实际编程中,运算符重载发挥了重要的作用,主要体现在以下几个方面:
可读性提升: 运算符重载使得代码更贴近问题领域的语言,使得代码读起来更自然、更易理解。例如,通过重载加法运算符,我们可以直接使用 object1 + object2
表达对象相加的语义,而无需调用繁琐的方法或函数。
灵活性增强: 自定义类型的运算符重载允许我们定义对象之间的交互方式。这种灵活性使得代码更容易适应不同的需求和上下文,提高了代码的通用性和可复用性。
语法糖的应用: 运算符重载为代码添加了一些语法糖,使得代码更加简洁、优雅。这不仅提高了代码的可读性,还有助于减少冗余代码的数量。
自定义类型的自然表达: 通过运算符重载,我们可以使自定义类型的对象表现出与内置类型相似的行为,使得使用这些类型的代码更加自然而流畅。
二、介绍
1.定义
通过运算符重载,用户可以为自己创建的类或结构体定义与标准运算符相对应的操作,使得这些类型的对象可以使用像内置类型一样的简洁语法来执行操作。
例如,对于自定义类 Complex
表示复数,我们可以通过运算符重载实现两个复数对象的加法:
class Complex {
public:Complex operator+(const Complex& other) const {Complex result;result.real = this->real + other.real;result.imaginary = this->imaginary + other.imaginary;return result;}private:double real;double imaginary;
};
在上述例子中,通过重载 +
运算符,我们使得 Complex
类的对象可以使用 +
运算符执行相应的复数加法,使得代码更加直观和易读。
2.语法
运算符重载的基本语法取决于编程语言,以下是C++中的一些关键点:
-
运算符重载函数的名称由
operator
关键字后接要重载的运算符决定。例如,要重载加法运算符,使用operator+
。MyClass operator+(const MyClass& obj) const {// 实现运算符行为 }
-
运算符重载函数可以是成员函数,也可以是友元函数。成员函数的左操作数是调用对象,右操作数是函数参数。友元函数不属于类,但可以访问类的私有成员。
-
参数的类型通常是按值传递或按常量引用传递,取决于是否需要修改参数的值。返回类型通常是一个新的对象,以便支持链式调用。
通过在类中定义运算符重载函数,我们可以为用户自定义类型赋予标准运算符的语义,使得这些类型可以通过与内置类型相似的语法进行操作,提高了代码的可读性和表达力。
三、示例
1.加法运算符重载
#include <iostream>class Point {
public:Point(double x, double y) : x(x), y(y) {}// 重载加法运算符作为成员函数Point operator+(const Point& other) const {return Point(this->x + other.x, this->y + other.y);}// 显示坐标void display() const {std::cout << "(" << x << ", " << y << ")" << std::endl;}private:double x;double y;
};int main() {Point p1(1.0, 2.0);Point p2(3.0, 4.0);// 使用重载的加法运算符Point result = p1 + p2;std::cout << "Result: ";result.display();return 0;
}
在这个例子中,我们将加法运算符 +
作为成员函数重载。通过这种方式,我们可以使用 p1 + p2
来直接实现两个点的坐标相加,使得代码更加简洁和直观。
2.一元运算符重载
考虑一个表示复数的类 Complex
,我们可以通过重载一元运算符实现复数的取负操作:
class Complex {
public:Complex(double real, double imaginary) : real(real), imaginary(imaginary) {}Complex operator-() const {return Complex(-real, -imaginary);}void display() const {std::cout << real << " + " << imaginary << "i" << std::endl;}private:double real;double imaginary;
};int main() {Complex c1(2.0, 3.0);Complex negativeC1 = -c1;std::cout << "Original: ";c1.display();std::cout << "Negation: ";negativeC1.display();return 0;
}
在上述例子中,通过重载一元运算符 -
,我们实现了复数的取负操作,使得 negativeC1 = -c1
变得简洁易读。
3.友元函数
假设我们有一个包含私有成员的类 PrivateClass
,我们可以使用友元函数来重载某个运算符,以便访问私有成员:
class PrivateClass {
private:int value;public:PrivateClass(int val) : value(val) {}// 声明友元函数friend PrivateClass operator+(const PrivateClass& obj1, const PrivateClass& obj2);
};// 定义友元函数
PrivateClass operator+(const PrivateClass& obj1, const PrivateClass& obj2) {return PrivateClass(obj1.value + obj2.value);
}int main() {PrivateClass obj1(5);PrivateClass obj2(10);PrivateClass result = obj1 + obj2;// 此处访问了 PrivateClass 的私有成员 valuestd::cout << "Result: " << result.value << std::endl;return 0;
}
在上述例子中,通过将友元函数声明为类的友元,我们可以在函数中访问 PrivateClass
的私有成员。友元函数通常用于需要访问类的私有成员的情况。
4.流插入和流提取
流插入运算符 <<
和流提取运算符 >>
的重载通常用于自定义对象的输出和输入格式。以下是一个示例,演示如何在类 Person
中重载这两个运算符:
#include <iostream>
#include <string>class Person {
public:Person(std::string name, int age) : name(name), age(age) {}// 重载流插入运算符 <<friend std::ostream& operator<<(std::ostream& os, const Person& person) {os << "Name: " << person.name << ", Age: " << person.age;return os;}// 重载流提取运算符 >>friend std::istream& operator>>(std::istream& is, Person& person) {std::cout << "Enter name: ";is >> person.name;std::cout << "Enter age: ";is >> person.age;return is;}private:std::string name;int age;
};int main() {Person person("John", 25);// 使用流插入运算符输出对象std::cout << "Person Information: " << person << std::endl;// 使用流提取运算符输入对象std::cout << "Enter new person information:" << std::endl;std::cin >> person;std::cout << "Updated Person Information: " << person << std::endl;return 0;
}
在这个例子中,我们通过重载 <<
和 >>
运算符,使得对象 Person
可以通过流的方式输出和输入。这样,我们可以使用 std::cout << person
来输出人物信息,以及使用 std::cin >> person
来从用户输入中读取新的信息。
5.自增自减运算符
自增和自减运算符 ++
和 --
可以作为前缀和后缀进行重载。以下是一个示例,演示如何在类 Counter
中重载这两个运算符:
#include <iostream>class Counter {
public:Counter(int value) : count(value) {}// 前缀自增运算符 ++Counter& operator++() {count++;return *this;}// 后缀自增运算符 ++Counter operator++(int) {Counter temp = *this;count++;return temp;}// 前缀自减运算符 --Counter& operator--() {count--;return *this;}// 后缀自减运算符 --Counter operator--(int) {Counter temp = *this;count--;return temp;}// 获取计数值int getCount() const {return count;}private:int count;
};int main() {Counter counter(5);// 前缀自增运算符 ++++counter;std::cout << "After prefix increment: " << counter.getCount() << std::endl;// 后缀自增运算符 ++Counter result = counter++;std::cout << "After postfix increment: " << result.getCount() << std::endl;// 前缀自减运算符 ----counter;std::cout << "After prefix decrement: " << counter.getCount() << std::endl;// 后缀自减运算符 --result = counter--;std::cout << "After postfix decrement: " << result.getCount() << std::endl;return 0;
}
在这个例子中,我们通过重载前缀和后缀的自增和自减运算符,使得 Counter
类的对象可以方便地进行增加和减少操作。
总结
运算符重载是一种强大的编程技术,允许用户定义的类型通过标准运算符执行自定义的操作。通过运算符重载,代码变得更加直观,可读性提高,使得类和对象的使用更加自然。在实际应用中,运算符重载常用于数学计算、矩阵操作等领域,提高了代码的灵活性和可维护性。
如果觉得这篇博客对你有帮助,可以点点关注哟,留下你们的点赞评论收藏,你们的关注与点赞就是我最大的鼓励~~😉😉我会持续创作滴!小海在这里谢谢各位~~
相关文章:
【C++】揭开运算符重载的神秘面纱
目录 一、引言 优点 二、介绍 1.定义 2.语法 三、示例 1.加法运算符重载 2.一元运算符重载 3.友元函数 4.流插入和流提取 5.自增自减运算符 总结 一、引言 何为运算符重载?运算符重载,是C中的一项强大特性,赋予了程序员在自定义类…...

竞赛保研 基于LSTM的天气预测 - 时间序列预测
0 前言 🔥 优质竞赛项目系列,今天要分享的是 机器学习大数据分析项目 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🧿 更多资料, 项目分享: https://gitee.com/dancheng-senior/po…...

前端常用的开发工具
前端常用的开发工具🔖 文章目录 前端常用的开发工具🔖1. Snipaste--截图工具2. ScreenToGif--gif图片录制3. Typora--Markdown编辑器4. notepad--文本代码编辑器5. uTools--多功能工具6. EV录屏--录屏软件7. Xmind--思维导图8. Apifox -- 接口调试9. Tor…...

鸿蒙开发语言介绍--ArkTS
1.编程语言介绍 ArkTS是HarmonyOS主力应用开发语言。它在TypeScript (简称TS)的基础上,匹配ArkUI框架,扩展了声明式UI、状态管理等相应的能力,让开发者以更简洁、更自然的方式开发跨端应用。 2.TypeScript简介 自行补充TypeScript知识吧。h…...

关于“Python”的核心知识点整理大全36
目录 13.4.4 向下移动外星人群并改变移动方向 game_functions.py alien_invasion.py 13.5 射杀外星人 13.5.1 检测子弹与外星人的碰撞 game_functions.py alien_invasion.py 13.5.2 为测试创建大子弹 13.5.3 生成新的外星人群 game_functions.py alien_invasion.py …...

安装nodejs,配置环境变量并将npm设置淘宝镜像源
安装nodejs并将npm设置淘宝镜像源 1. 下载nodejs 个人不喜欢安装包,所以是下载zip包的方式。这里我下载的node 14解压包版本 下载地址如下:https://nodejs.org/dist/v14.15.1/node-v14.15.1-win-x64.zip 想要其他版本的小伙伴去https://nodejs.org/di…...

12.18构建哈夫曼树(优先队列),图的存储方式,一些细节(auto,pair用法,结构体指针)
为结构体自身时,用.调用成员变量;为结构体指针时,用->调用成员变量 所以存在结构体数组时,调用数组元素里的成员变量,就是要用. 结构体自身只有在new时才会创建出来,而其指针可以随意创建 在用new时&…...

《Python》面试常问:深拷贝、浅拷贝、赋值之间的关系(附可变与不可变)【用图文讲清楚!】
背景 想必大家面试或者平时学习经常遇到问python的深拷贝、浅拷贝和赋值之间的区别了吧?看网上的文章很多写的比较抽象,小白接收的难度有点大,于是乎也想自己整个文章出来供参考 可变与不可变 讲深拷贝和浅拷贝之前想讲讲什么是可变数据类型…...

使用PE信息查看工具和Dependency Walker工具排查因为库版本不对导致程序启动报错问题
目录 1、问题说明 2、问题分析思路 3、问题分析过程 3.1、使用Dependency Walker打开软件主程序,查看库与库的依赖关系,查看出问题的库 3.2、使用PE工具查看dll库的时间戳 3.3、解决办法 4、最后 VC常用功能开发汇总(专栏文章列表&…...
Python编程题目答疑「Python一对一辅导考试真题解析」
你好,我是悦创。 待会更新~ 更新计划 答案 题目 记得点赞收藏! 题目 之后更新 Solution Question 1 # 读取输入 a float(input("请输入实数 a: ")) b float(input("请输入实数 b: ")) c float(input("请输…...

Python---搭建Python自带静态Web服务器
1. 静态Web服务器是什么? 可以为发出请求的浏览器提供静态文档的程序。 平时我们浏览百度新闻数据的时候,每天的新闻数据都会发生变化,那访问的这个页面就是动态的,而我们开发的是静态的,页面的数据不会发生变化。 …...
在服务器上部署SpringBoot项目jar包
以下是在服务器上部署Spring Boot项目jar包的步骤: 打包项目: 使用IDEA或者命令行工具(如Maven或Gradle)将Spring Boot项目打包为一个可执行的jar文件。如果使用Maven,可以在项目的根目录下运行以下命令来打包项目&…...

[python]python实现对jenkins 的任务触发
目录 关键词平台说明背景一、安装 python-jenkins 库二、code三、运行 Python 脚本四、注意事项 关键词 python、excel、DBC、jenkins 平台说明 项目Valuepython版本3.6 背景 用python实现对jenkins 的任务触发。 一、安装 python-jenkins 库 pip install python-jenkin…...

Python生成圣诞节贺卡-代码案例剖析【第18篇—python圣诞节系列】
文章目录 ❄️Python制作圣诞节贺卡🐬展示效果🌸代码🌴代码剖析 ❄️Python制作圣诞树贺卡🐬展示效果🌸代码🌴代码剖析🌸总结 🎅圣诞节快乐! ❄️Python制作圣诞节贺卡 …...

深度剖析Ajax实现方式(原生框架、JQuery、Axios,Fetch)
Ajax学习 简介: Ajax 代表异步 JavaScript 和 XML(Asynchronous JavaScript and XML)的缩写。它指的是一种在网页开发中使用的技术,通过在后台与服务器进行数据交换,实现页面内容的更新,而无需刷新整个…...

任天堂,steam游戏机通过type-c给VR投屏与PD快速充电的方案 三type-c口投屏转接器
游戏手柄这个概念,最早要追溯到二十年前玩FC游戏的时候,那时候超级玛丽成为了许多人童年里难忘的回忆,虽然长大了才知道超级玛丽是翻译错误,应该是任天堂的超级马里奥,不过这并不影响大家对他的喜爱。 当时FC家用机手柄…...

Flink系列之:Checkpoints 与 Savepoints
Flink系列之:Checkpoints 与 Savepoints 一、概述二、功能和限制 一、概述 从概念上讲,Flink 的 savepoints 与 checkpoints 的不同之处类似于传统数据库系统中的备份与恢复日志之间的差异。 Checkpoints 的主要目的是为意外失败的作业提供恢复机制。 …...

【优质书籍推荐】LoRA微调的技巧和方法
大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。…...

Linux一行命令配置jdk环境
使用方法: 压缩包上传 到/opt, 更换命令中对应的jdk包名即可。 注意点:jdk-8u151-linux-x64.tar.gz 解压后名字是jdk1.8.0_151 sudo tar -zxvf jdk-8u151-linux-x64.tar.gz -C /opt && echo export JAVA_HOME/opt/jdk1.8.0_151 | sudo tee -a …...
从0开始刷剑指Offer
剑指Offer题解 剑指 Offer 11. 旋转数组的最小数字 思路: 二分O(logn) class Solution {public int stockManagement(int[] stock) {int l 0;int r stock.length - 1;while(l < r && stock[0] stock[r]) r --;if(stock[r] > stock[l]) return stock[0];whi…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...

visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...

关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...

P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...
掌握 HTTP 请求:理解 cURL GET 语法
cURL 是一个强大的命令行工具,用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中,cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...