【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…...
黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门  bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
Android写一个捕获全局异常的工具类
项目开发和实际运行过程中难免会遇到异常发生,系统提供了一个可以捕获全局异常的工具Uncaughtexceptionhandler,它是Thread的子类(就是package java.lang;里线程的Thread)。本文将利用它将设备信息、报错信息以及错误的发生时间都…...
