当前位置: 首页 > news >正文

C++学习笔记----8、掌握类与对象(六)---- 操作符重载(1)

        经常在对象上执行如相加,比较,文件传输等操作。例如,spreadsheet只有在可以在上面执行自述运算才有用,比如对整行的单元格求和。所有这些都可以通过重载操作符来完成。

        许多人发现操作符重载的语法复杂而令人迷惑。至少一开始是这样。真实情况是想让事情更简单。在本节你会发现,那并不意味着写类时更简单,只是使用类时更简单。关键点是让新类与内建像int与double这样的类型一样简单:使用+来使对象相加要比记住不管是add()或是sum()这样的成员函数名要容易多了。

        注意:作为服务给客户提供类的操作符重载。

        在这一点上,你可能会想到底哪些操作符可以重载呢?答案是几乎所有--甚至是你没有听说过的。本章会浮光掠影地简单涉及一下:赋值操作符在本章的前面 已经解释过了,而本节要介绍的是基础的算术操作符,缩写的算术操作符,以及比较操作符。重载流插入与释放操作符也比较有用。还有,有一些麻烦但是又比较有趣的东东,一开始你可能并不想用操作符重载来做。在标准库中大量使用操作符重载。以后我们会解释怎么以及什么时候重载其他的操作符。以及标准库方面的内容。

1、例子:SpreadsheetCell的另外内容的实现

        在真正的面向对象的编程风格中,SpreadsheetCell对象应该能够把自己与其它SpreadsheetCell对象相加。将一个单元格与另一个单元格相加生成结果为第三个单元格。这并不会改变原来的任一单元格。SpreadsheetCell相加的意思就是单元格值的相加。

1.1、第一次尝试:加成员函数

        可以为SpreadsheetCell类像这样声明与定义add()成员函数:

export class SpreadsheetCell
{
public:SpreadsheetCell add(const SpreadsheetCell& cell) const;// Omitted for brevity
};

        该成员函数将两个单元格相加,返回一个新的第三个单元格 ,其值是前两个的和。声明为const并且 用一个const SpreadsheetCell的引用是因为add()不会改变任意一个源单元格。下面是其实现:

SpreadsheetCell SpreadsheetCell::add(const SpreadsheetCell& cell) const
{return SpreadsheetCell { getValue() + cell.getValue() };
}

        可以像这样来使用add()成员函数:

SpreadsheetCell myCell { 4 }, anotherCell { 5 };
SpreadsheetCell aThirdCell { myCell.add(anotherCell) };
auto aFourthCell { aThirdCell.add(anotherCell) };

        这也可以达到目的,但是有一点儿繁琐,我们可以做得更好。

1.2、第二次尝试:重载操作符+作为成员函数

        用加号类似于两个int或者两个double的方式来将两个单元格相加会比较方便--有点儿像下面这样:

SpreadsheetCell myCell { 4 }, anotherCell { 5 };
SpreadsheetCell aThirdCell { myCell + anotherCell };
auto aFourthCell { aThirdCell + anotherCell };

        c++允许你写自己的加号版本,叫做加操作符,来正确地作用于类。为了做到这一点,写一个名字叫做operator+的成员函数,看起来像这样:

export class SpreadsheetCell
{
public:SpreadsheetCell operator+(const SpreadsheetCell& cell) const;// Omitted for brevity
};

        注意:在operator与加号之间可以加入空格。例如,可以将operator+写成operator +。我们还是使用没有空格的风格。

        重载的operator+成员函数的定义与add()成员函数的实现是一样的:

SpreadsheetCell SpreadsheetCell::operator+(const SpreadsheetCell& cell) const
{return SpreadsheetCell { getValue() + cell.getValue() };
}

        现在你就可以使用前面展示的加号操作符来将两个单元格 相加了。

        我们还是比较习惯于这种语法。不要过于担心奇怪的成员函数名operator+----它就是一个类似于foo或add的名字而已。为了理解语法的其余部分,它有助于理解真实发生的情况。当c++编译器解析程序时,遇到比如说+,-,=,或<<这样的操作符,它会用operator+,operator-,operator=,或operator<<这样的名字来找函数或成员函数,特别是,带有适合的参数的。例如,当编译器看到下面的代码行,它会尝试在SpreadsheetCell类中去找成员函数名字为operator+,接受另一个SpreadsheetCell作为参数(或者,在本章后面会讨论到的,接受两个SpreadsheetCell参数的全局函数,名字叫做operator+):

SpreadsheetCell aThirdCell { myCell + anotherCell };

        如果SpreadsheetCell类包含这样一个operator+成员函数,上面的行就会被翻译成这样:

SpreadsheetCell aThirdCell { myCell.operator+(anotherCell) };

        注意,operator+没有要求其参数的对象是与它所写的类是同一种类型。你可以写一个SpreadsheetCell的operator+,拿一个Spreadsheet去加到SpreadsheetCell。这对于程序员是讲不通的,但是编译器是允许的。下一节会给出一个SpreadsheetCell的operator+接受double值的例子。

        也要注意,可以让operator+返回你想的任何类型。然而,应该遵循最少惊奇的原则;也就是说,operator+的返回类型通常应该是用户想要的。

1.2.1、隐式转换

        令人吃惊的是,一旦写完前面所示的operator+,不但可以将两个单元格相加,也可以将一个单元格加到一个string_view,一个double,或一个int!下面是一些例子:

SpreadsheetCell myCell { 4 }, aThirdCell;
string str { "hello" };
aThirdCell = myCell + string_view{ str };
aThirdCell = myCell + 5.6;
aThirdCell = myCell + 4;

        这些代码能跑的原因是编译器会比尝试找到合适的operator+的所指的正确的类型更多的工作。编译器也会尝试找到合适的类型转换。SpreadsheetCell类有转换构造函数将double或string_view转换成一个SpreadsheetCell。在前面的例子中,当编译器看到一个SpreadsheetCell尝试将自身加到一个double上,它发现SpreadsheetCell构造函数用了double并且 构建了一个临时的SpreadsheetCell对象传递给operator+。同样的,当编译器看到代码行尝试将一个SpreadsheetCell加到一个string_view上时,它会调用string_view SpreadsheetCell构造函数生成一个临时的SpreadsheetCell传递给operator+。

        要记住,虽然使用隐式转换构造函数可以效率不高,因为要生成临时对象。在这个例子中,为了避免隐式构建与double相加,可以写如下的第二个operator+:

SpreadsheetCell SpreadsheetCell::operator+(double rhs) const
{return SpreadsheetCell { getValue() + rhs };
}

相关文章:

C++学习笔记----8、掌握类与对象(六)---- 操作符重载(1)

经常在对象上执行如相加&#xff0c;比较&#xff0c;文件传输等操作。例如&#xff0c;spreadsheet只有在可以在上面执行自述运算才有用&#xff0c;比如对整行的单元格求和。所有这些都可以通过重载操作符来完成。 许多人发现操作符重载的语法复杂而令人迷惑。至少一开始是这…...

Ascend C 自定义算子开发:高效的算子实现

Ascend C 自定义算子开发&#xff1a;高效的算子实现 在 Ascend C 平台上&#xff0c;开发自定义算子能够充分发挥硬件的性能优势&#xff0c;帮助开发者针对不同的应用场景进行优化。本文将以 AddCustom 算子为例&#xff0c;介绍 Ascend C 中自定义算子的开发流程及关键技术…...

面向对象技术——设计模式

目录 层次结构 具体设计模式分类 创建型模式&#xff08;处理创建对象&#xff09; 结构型模式&#xff08;处理类和对象的组合&#xff09; 行为型模式&#xff08;描述类或者对象的交互行为&#xff09; 创建型设计模式 ​编辑 结构型设计模式 行为型设计模式​编辑 …...

2024 Mysql基础与进阶操作系列之MySQL触发器详解(20)作者——LJS[你个小黑子这都还学不会嘛?你是真爱粉嘛?真是的 ~;以后请别侮辱我家鸽鸽]

欢迎各位彦祖与热巴畅游本人专栏与博客 你的三连是我最大的动力 以下图片仅代表专栏特色 [点击箭头指向的专栏名即可闪现] 专栏跑道一 ➡️ MYSQL REDIS Advance operation 专栏跑道二➡️ 24 Network Security -LJS ​ ​ ​ 专栏跑道三 ➡️HCIP&#xff1b;H3C-SE;CCIP——…...

找不到concrt140.dll如何修复,快来试试这6种解决方法

concrt140.dll是微软Visual C 2015 Redistributable Package中的一个重要动态链接库文件&#xff0c;它在许多Windows应用程序中扮演着关键角色。本文将详细探讨concrt140.dll丢失的原因、影响、解决方法以及预防措施&#xff0c;帮助用户更好地理解和应对这一问题。 一、什么是…...

年会工作会议会务报名签到小程序开源版开发

年会工作会议会务报名签到小程序开源版开发 会议管理微信小程序&#xff0c;对会议流程、开支、数量、标准、供应商提供一种标准化的管理方法。以达到量化成本节约&#xff0c;风险缓解和服务质量提升的目的。适用于大型论坛、峰会、学术会议、政府大会、合作伙伴大会、经销商…...

UE C++ 实时加载模型的总结

一.总体思路&#xff1a; 如果实时加载UE模型&#xff0c;需要先将之前的模型删除。再生成出来&#xff0c;放在根节点&#xff0c;保持相对位置&#xff0c;相对的俯仰角。 void AAirForce::LoadWeapon(int ID, int Type, double X, double Y, double Z) {//m_weaponMap.Emp…...

实施威胁暴露管理、降低网络风险暴露的最佳实践

随着传统漏洞管理的发展&#xff0c;TEM 解决了因攻击面扩大和安全工具分散而产生的巨大风险。 主动式 TEM 方法优先考虑风险并与现有安全工具无缝集成&#xff0c;使组织能够在威胁被有效利用之前缓解威胁。 为什么威胁暴露管理 (TEM) 在现代网络安全策略中变得至关重要&…...

51.哀家要长脑子了!

1.P1003 [NOIP2011 提高组] 铺地毯​​​​​​ 重复 模拟 要求覆盖在最上面的地毯编号&#xff0c;用四个数组abgk分别记录地毯起点的左下角横纵坐标&#xff0c;地毯的长度宽度&#xff0c;输入的坐标x y 当它满足大于等于左下角坐标 并且 小于等于 地毯左下角横纵坐标的时候…...

Overleaf 无法显示图片

问题描述 在Overleaf中的代码为&#xff1a; \begin{figure}\centering\includegraphics[width0.98\linewidth]{figures/test.png}\caption{This is a test.}\label{fig:test} \end{figure}但无法正常显示图片&#xff1a; 解决方案 修改编译模式为正常Normal而非快速Fast …...

如何实现 C/C++ 与 Python 的通信?

在现代编程中&#xff0c;C/C与Python的通信已经成为一种趋势&#xff0c;尤其是在需要高性能和灵活性的场景中。本文将深入探讨如何实现这两者之间的互通&#xff0c;包括基础和高级方法&#xff0c;帮助大家在混合编程中游刃有余。 C/C 调用 Python&#xff08;基础篇&#…...

音视频入门基础:FLV专题(13)——FFmpeg源码中,解析任意Type值的SCRIPTDATAVALUE类型的实现

一、SCRIPTDATAVALUE类型 从《音视频入门基础&#xff1a;FLV专题&#xff08;9&#xff09;——Script Tag简介》中可以知道&#xff0c;根据《video_file_format_spec_v10_1.pdf》第80到81页&#xff0c;SCRIPTDATAVALUE类型由一个8位&#xff08;1字节&#xff09;的Type和…...

jvm里的metaspace oom 排查问题思路-使用MAT

文章目录 metapace oom 问题排查点-1-duplicate class 数量排查点-2-classloader 数量一些可能迷惑人的方向 metapace oom 问题 metapace 问题都是由加载的class 太多&#xff0c;导致内存不够报出来的。 排查点-1-duplicate class 数量 首先看这里&#xff0c;通常一个clas…...

2025舜宇招聘【内推码】

【2025内推码】 DSwNQ9yu DSJXN8Mr 舜宇集团2025届全球校园招聘正式启动&#xff01;&#xff01;&#xff01; 专业需求&#xff1a;机械、自动化、电子、电气、通信、控制、测控、计算机、软件、物理、光学等专业&#xff1b; 工作地点&#xff1a;宁波余姚、浙江杭州、广东…...

APP自动化搭建与应用

APP自动化环境搭建 用于做APP端UI自动化&#xff0c;adb连接手机设备。 需要的工具java编辑器&#xff1a;jdk、Android-sdk软件开发工具组、appium的python客户端、nodes.js、夜神模拟器、apk包、uiautomatorviewer 第一步&#xff1a;安装sdk&#xff0c;里面包含建立工具bu…...

kafka-windows集群部署

kafka-windows集群部署目录 文章目录 kafka-windows集群部署目录前言一、复制出来四个kafka文件夹二、修改集群每个kafka的配置文件四、启动zookeeper&#xff0c;kafka集群 前言 部署本文步骤可以先阅读这一篇博客&#xff0c;这篇是关于单机kafka部署测试的。本文用到的文件…...

4个顶级的大模型推理引擎

LLM 在文本生成应用中表现出色&#xff0c;例如具有高理解度和流畅度的聊天和代码完成模型。然而&#xff0c;它们的庞大规模也给推理带来了挑战。基本推理速度很慢&#xff0c;因为 LLM 会逐个生成文本标记&#xff0c;需要对每个下一个标记进行重复调用。随着输入序列的增长&…...

Oracle中ADD_MONTHS()函数详解

文章目录 前言一、ADD_MONTHS()的语法二、主要用途三、测试用例总结 前言 在Oracle数据库中&#xff0c;ADD_MONTHS()函数用于在日期中添加指定的月数。 一、ADD_MONTHS()的语法 ADD_MONTHS(date, n) 其中&#xff0c;date是一个日期值&#xff0c;n是一个整数值&#xff0c…...

【SQL】掌握SQL查询技巧:高效数据整合与查询优化

目录 1. SQL 的基本构成2. SQL 联接&#xff08;JOIN&#xff09;2.1 内联接&#xff08;INNER JOIN&#xff09;2.2 外联接&#xff08;OUTER JOIN&#xff09;2.2.1 左外联接&#xff08;LEFT JOIN&#xff09;2.2.2 右外联接&#xff08;RIGHT JOIN&#xff09;2.2.3 全外联…...

一个月学会Java 第5天 控制结构

Day5 控制结构 这么叫可能有些就算有基础的人也看不懂&#xff0c;其实就是if-else、switch-case、for、while、do-while这几个&#xff0c;没基础的听到了这个也不要慌张&#xff0c;这几个是程序的基础&#xff0c;多多训练就好 第一章 顺序结构 这章其实没有什么好讲的&…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

LRU 缓存机制详解与实现(Java版) + 力扣解决

&#x1f4cc; LRU 缓存机制详解与实现&#xff08;Java版&#xff09; 一、&#x1f4d6; 问题背景 在日常开发中&#xff0c;我们经常会使用 缓存&#xff08;Cache&#xff09; 来提升性能。但由于内存有限&#xff0c;缓存不可能无限增长&#xff0c;于是需要策略决定&am…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)

目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 &#xff08;1&#xff09;输入单引号 &#xff08;2&#xff09;万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...

SpringAI实战:ChatModel智能对话全解

一、引言&#xff1a;Spring AI 与 Chat Model 的核心价值 &#x1f680; 在 Java 生态中集成大模型能力&#xff0c;Spring AI 提供了高效的解决方案 &#x1f916;。其中 Chat Model 作为核心交互组件&#xff0c;通过标准化接口简化了与大语言模型&#xff08;LLM&#xff0…...

【iOS】 Block再学习

iOS Block再学习 文章目录 iOS Block再学习前言Block的三种类型__ NSGlobalBlock____ NSMallocBlock____ NSStackBlock__小结 Block底层分析Block的结构捕获自由变量捕获全局(静态)变量捕获静态变量__block修饰符forwarding指针 Block的copy时机block作为函数返回值将block赋给…...