C++学习笔记-operator关键字:重载与自定义操作符

在C++编程中,operator关键字扮演着极其重要且独特的角色。它允许开发者为内置类型或自定义类型重载或定义新的操作符行为。这一特性极大地增强了C++的表达能力,使得代码更加直观、易于理解和维护。本文将深入探讨C++中operator关键字的使用,包括操作符重载和自定义操作符的基本概念、语法、使用场景以及注意事项。

一、操作符重载定义(Operator Overloading)

1.1 基本概念

操作符重载是C++语言的一个特性,它允许你重新定义或“重载”已存在的操作符(如+、-、*、/等)在特定类型上的行为。这意呀着,你可以为自定义类型(如类)定义这些操作符如何工作,使得它们能够像内置类型那样进行算术运算或逻辑操作。

1.2 误区

需要注意的是,C++并不支持真正意义上的“自定义操作符”,即你不能创造全新的、从未在C++中定义过的操作符符号。然而,你可以通过重载现有的操作符来赋予它们新的意义,这在一定程度上实现了类似自定义操作符的效果。

二、操作符重载实现

2.1 重载规则

在C++中,不是所有的操作符都可以被重载。以下是一些可以重载的操作符列表(注意,这里只列出了部分常用操作符,完整列表请参考C++标准):

  • 算术操作符:+、-、*、/、%、++、–
  • 关系操作符:==、!=、<、<=、>、>=
  • 逻辑操作符:!、&&、||(但通常不建议重载这些操作符,因为它们的行为与短路评估紧密相关)
  • 位操作符:&、|、^、~、<<、>>
  • 赋值操作符:=、+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>=
  • 其他操作符:()(函数调用)、[](下标)、->*(指向成员的指针运算符)、new和delete(虽然这些操作符通常不被重载,但了解它们的存在是有益的)

此外,还有一些操作符是不能被重载的,如.(成员访问操作符)、::(作用域解析操作符)、sizeof(获取对象或类型大小)、typeid(获取类型的类型信息)等。

2.2 重载方式

操作符重载可以通过成员函数或友元函数来实现。选择哪种方式取决于操作符需要访问的类成员以及操作符的预期行为。

  • 成员函数重载:当操作符需要一个操作数(通常是左侧操作数)作为类的一个对象时,通常使用成员函数重载。例如,重载+操作符以实现两个自定义类型对象的加法时,如果加号左侧的对象是自定义类型的实例,则可以将+操作符重载为成员函数。
  • 友元函数重载:当操作符需要访问类的私有或保护成员,或者当两个操作数都是自定义类型时,通常使用友元函数重载。友元函数不是类的成员函数,但它可以访问类的私有和保护成员。因此,它提供了一种灵活的方式来重载需要访问类内部状态的操作符。

2.3注意事项

  • 不要重载所有操作符:只重载那些对类有意义的操作符,避免造成混淆。
  • 保持操作符的语义:尽量保持操作符的直观性和原有语义,避免误导使用者。
  • 避免重载&&、||和,:这些操作符的短路行为在重载时可能难以正确实现,且容易引发错误。
  • 成员函数与友元函数的选择:根据操作数的类型和操作符的语义来选择合适的重载方式。

2.4 语法示例

以下是一个简单的示例,展示了如何为自定义的Complex类重载+操作符:

#include <iostream>  class Complex {  
public:  double real, imag;  // 构造函数  Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {}  // 成员函数重载+操作符  // 注意:这里我们返回了一个Complex对象的副本  Complex operator+(const Complex& rhs) const {  return Complex(real + rhs.real, imag + rhs.imag);  }  // 声明友元函数来重载<<操作符  friend std::ostream& operator<<(std::ostream& os, const Complex& c);  
};  // 定义友元函数来重载<<操作符  
// 注意:这个函数不是Complex类的成员函数  
std::ostream& operator<<(std::ostream& os, const Complex& c) {  os << c.real << (c.imag >= 0 ? "+" : "") << c.imag << "i";  // 如果imag为负,则不打印加号  return os; // 返回ostream对象以支持链式调用  
}  int main() {  Complex c1(1, 2);  Complex c2(3, 4);  // 使用重载的+操作符  Complex c3 = c1 + c2;  // 使用重载的<<操作符输出复数  std::cout << "c1 + c2 = " << c3 << std::endl;  return 0;  
}

代码中在自定义一个Complex(复数)类,成员变量有real(实部)和imag(虚部)。然后,我们为这个类重载了+操作符,使其能够接受另一个Complex对象作为参数,并返回一个新的Complex对象,该对象包含了两个复数相加的结果。

接下来,我们声明了operator<<作为Complex类的友元函数,并在类定义外部对其进行了定义。这个函数接受一个std::ostream引用和一个const Complex&引用作为参数,将复数以“实部+虚部i”的格式输出到流中(如果虚部为正,则输出加号;如果虚部为负,则不输出加号),并返回std::ostream对象的引用以支持链式调用。

在main函数中,我们创建了两个Complex对象c1和c2,使用重载的+操作符将它们相加,得到结果c3,然后使用重载的<<操作符将c3输出到控制台。输出结果如下:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/49500.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Interesting bug caused by getattr

题意&#xff1a;由 getattr 引起的有趣的 bug 问题背景&#xff1a; I try to train 8 CNN models with the same structures simultaneously. After training a model on a batch, I need to synchronize the weights of the feature extraction layers in other 7 models. …

Elasticsearch:Golang ECS 日志记录 - zap

ECS 记录器是你最喜欢的日志库的格式化程序/编码器插件。它们可让你轻松地将日志格式化为与 ECS 兼容的 JSON。 编码器以 JSON 格式记录日志&#xff0c;并在可能的情况下依赖默认的 zapcore/json_encoder。它还处理 ECS 错误格式的错误字段记录。 默认情况下&#xff0c;会添…

OpenWrt 为软件包和docker空间扩容

参考资料 【openwrt折腾日记】解决openwrt固件刷入后磁盘空间默认小的问题&#xff0c;关联openwrt磁盘扩容空间扩容【openwrt分区扩容】轻松解决空间可用不足的尴尬丨老李一瓶奶油的YouTube 划分空间 参考一瓶奶油的YouTube 系统 -> 磁盘管理 -> 磁盘 -> 修改 格…

【机器学习】不同操作系统下如何安装Jupyter Notebook和Anaconda

引言 Jupyter Notebook 是一个非常流行的开源Web应用程序&#xff0c;允许你创建和共享包含代码、方程、可视化和解释性文本的文档 文章目录 引言一、如何安装Jupyter Notebook1.1 对于Windows用户1.2 对于macOS用户1.3 对于Linux用户&#xff1a; 二、如何安装Anaconda2.1 对于…

基于Element UI内置的Select下拉和Tree树形组件,组合封装的树状下拉选择器

目录 简述 效果 功能描述 代码实现 总结 简述 基于Element UI内置的Select下拉和Tree树形组件&#xff0c;组合封装的树状下拉选择器。 效果 先看效果&#xff1a; 下拉状态&#xff1a; 选择后状态&#xff1a; 选择的数据&#xff1a; 功能描述 1、加载树结构&…

Linux云计算 |【第一阶段】SERVICES-DAY2

主要内容&#xff1a; DNS服务基础及搭建、特殊解析(针对地址库文件&#xff1a;DNS轮询 DNS泛域名解析 DNS别名&#xff09;、缓存DNS&#xff08;全局转发forwarders&#xff09;、DNS递归迭代&#xff08;子域授权&#xff09;、DNS主从架构搭建、DNS主从数据同步 一、DNS工…

【技术升级】Docker环境下Nacos平滑升级攻略,安全配置一步到位

目前项目当中使用的Nacos版本为2.0.2&#xff0c;该版本可能存在一定的安全风险。软件的安全性是一个持续关注的问题&#xff0c;尤其是对于像Nacos这样的服务发现与配置管理平台&#xff0c;它在微服务架构中扮演着核心角色。随着新版本的发布&#xff0c;开发团队会修复已知的…

光伏模拟器应用

太阳能光伏 (PV) 模拟器是一种可编程电源&#xff0c;用于模拟太阳能电池板。模拟器具有快速瞬态响应&#xff0c;可响应负载条件的变化并保持电压-电流特性的输出。 用户可以根据系统规格定义太阳能电池板配置&#xff0c;并通过选择环境条件来选择适当的环境条件进行模拟。用…

pytest+allure

安装 下载&#xff1a;github win环境下载zip 环境变量&#xff1a; pycharm&#xff1a; pip install allure-pytest 验证安装 生成结果&#xff1a; if __name__ __main__:pytest.main([-s,test_createTag2.py,--alluredir,result]) 生成报告&#xff1a; allure gener…

如何查看Kafka的偏移量offset

本文介绍三种方法查看Kafka的偏移量offset。 1. API&#xff1a;ConsumerRecord的offset()方法查看offset。 2. API&#xff1a;KafkaConsumer的position(TopicPartition partition)方法查看offset。 3. 命令行&#xff1a;kafka-consumer-groups.sh命令查看offset。 前提条…

前置-Linux相关知识速记

linux Linux命令大全 [!IMPORTANT] chown-chmod-ls-chgrp-cdpwd-mkdir-rmdir-cp-rm-mv-cat-tac-nl-more-less-head-tail 应用领域 通常服务器使用 LAMP&#xff08;Linux Apache MySQL PHP&#xff09;或 LNMP&#xff08;Linux Nginx MySQL PHP&#xff09;组合。 目前…

STM32 BootLoader 刷新项目 (五) 获取软件版本号-命令0x51

STM32 BootLoader 刷新项目 (五) 获取软件版本号-命令0x51 下面我们来讲解第一个指令&#xff0c;获取软件版本号命令-0x51. 在BootLoader中获取软件版本号的操作有多个重要的作用&#xff0c;具体如下&#xff1a; 版本管理&#xff1a; 识别当前版本&#xff1a;通过获取软…

无人机上磁航技术详解

磁航技术&#xff0c;也被称为地磁导航&#xff0c;是一种利用地球磁场信息来实现导航的技术。在无人机领域&#xff0c;磁航技术主要用于辅助惯性导航系统&#xff08;INS&#xff09;进行航向角的测量与校正&#xff0c;提高无人机的飞行稳定性和准确性。其技术原理是&#x…

vue3 + antd vue 纯前端 基于xlsx 实现导入excel 转 json,将json数据转换XLSX导出(模版下载)

一、导入 0、关键代码 // 安装插件 npm i xlsx/yarn add xlsx // 导入xlsx import * as XLSX from xlsx; 点击提交的时候才整理数据。上传的时候文件保存在 state.form.file[0] 中的 // 定义字段映射关系 const fieldMap {sheet2json: {技能名称: skill_name,技能等级: …

微服务实战系列之玩转Docker(六)

前言 刚进入大暑&#xff0c;“清凉不肯来&#xff0c;烈日不肯暮”&#xff0c;空调开到晚&#xff0c;还是满身汗。——碎碎念 我们知道&#xff0c;仓库可见于不同领域&#xff0c;比如粮食仓库、数据仓库。在容器领域&#xff0c;自然也有镜像仓库&#xff08;registry&…

代码随想录——零钱兑换Ⅱ(Leetcode518)

题目链接 完全背包 class Solution {public int change(int amount, int[] coins) {int[] dp new int[amount 1];dp[0] 1;for(int i 0; i < coins.length; i){for(int j coins[i]; j < amount; j){dp[j] dp[j - coins[i]];}}return dp[amount];} }本题为组合问题…

uni-app AppStore Connect上传拒绝汇总

1.Guideline 2.3.3 - Performance - Accurate Metadata 问题是图片不对&#xff0c;最好是自己截图&#xff0c;然后用香蕉云编 上传图片合成图片 2.Guideline 5.1.2 - Legal - Privacy - Data Use and Sharing 解决办法&#xff1a;在uniapp manifest.json找到 APP常用其他…

【软考】系统集成项目管理工程师【第二版】

&#x1f44a;重要通知&#x1f44a; &#x1f44a; 1. 2024年中考上半年取消&#xff0c;改下半年&#x1f44a; &#x1f44a; 2. 2024下半年 使用《系统集成项目管理工程师教程》第三版&#x1f44a; &#x1f44a; 3. 为了方便大家学习&#xff0c;博主正在整理第三版 &am…

使用uniapp开发小程序(基础篇)

本文章只介绍微信小程序的开发流程&#xff0c;如果需要了解其他平台的开发的流程的话&#xff0c;后续根据情况更新相应的文章,也可以根据uniapp官网的链接了解不同平台的开发流程 HBuilderX使用&#xff1a;https://uniapp.dcloud.net.cn/quickstart-hx.html 开发工具 开始…

# OpenCV 图像预处理—形态学:膨胀、腐蚀、开运算、闭运算 原理详解

文章目录 形态学概念膨胀使用膨胀操作来修复裂痕示例代码关键解析&#xff1a; 腐蚀使用腐蚀操作消除噪点示例代码&#xff1a; 开运算—先腐蚀后膨胀闭运算—先膨胀后腐蚀 形态学概念 首先看这两张图片 一张图周围有大大小小的噪音和彩点&#xff0c;另一张图片中字母有间隙&…