【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…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...

C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...