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

news2024/9/24 5:24:24

在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.coloradmin.cn/o/1944275.html

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

相关文章

【ffmpeg命令入门】ffplay常用命令

文章目录 前言ffplay的简介FFplay 的基本用法常用参数及其作用示例 效果演示图播放普通视频播放网络媒体流RTSP 总结 前言 FFplay 是 FFmpeg 套件中的一个强大的媒体播放器&#xff0c;它基于命令行接口&#xff0c;允许用户以灵活且高效的方式播放音频和视频文件。作为一个简…

vscode 寻找全部分支的提交

vscode 寻找全部分支的提交 Git Graph

UE5 C++跑酷练习(Part2)

一.首先GameMode里有Actor数组&#xff0c;组装直线路&#xff0c;和左右路 #include "CoreMinimal.h" #include "GameFramework/GameModeBase.h" #include "RunGANGameMode.generated.h"UCLASS(minimalapi) class ARunGANGameMode : public AG…

【目录】8051汇编与C语言系列教程

8051汇编与C语言系列教程 作者将狼才鲸创建日期2024-07-23 CSDN文章地址&#xff1a;【目录】8051汇编与C语言系列教程本Gitee仓库原始地址&#xff1a;才鲸嵌入式/8051_c51_单片机从汇编到C_从Boot到应用实践教程 一、本教程目录 序号教程名称简述教程链接1点亮LCD灯通过IO…

【技术支持案例】使用S32K144+NSD8381驱动电子膨胀阀

文章目录 1. 前言2. 问题描述3. 理论分析3.1 NSD8381如何连接电机3.2 S32K144和NSD8381的软件配置 4.测试验证4.1 测试环境4.2 测试效果4.3 测试记录 1. 前言 最近有客户在使用S32K144NSD8381驱动电子膨胀阀时&#xff0c;遇到无法正常驱动电子膨胀阀的情况。因为笔者也是刚开…

分享一个Springer模板关于论文作者和单位信息的修改范例,以及Applied Intelligence期刊latex模板的下载链接

在这篇文章中&#xff0c;我写一些关于解决springer期刊提供的LaTex模板参考文献格式为作者年份时的顺序问题以及如何在正文中将参考文献格式引用成[1]这种数字格式类似的经验&#xff0c;该篇帖子里还分享了一个大佬关于springer模板完整的修改流程&#xff0c;有需要的伙伴可…

如何实现可视化、智能化、自动化的文件采集?一文了解

内部数据文件采集需求在多个行业中都非常重要&#xff0c;以下是一些涉及此场景需求的行业&#xff1a; 1.大数据行业&#xff1a;随着大数据的行业应用不断深入&#xff0c;物联网、智能家居、数字政务等领域的大数据技术应用逐渐成熟&#xff0c;数据采集的需求也将被逐步激…

0723,UDP通信(聪明小辉聪明小辉),HTTP协议

我就是一个爱屋及乌的人&#xff01;&#xff01;&#xff01;&#xff01; #include "network_disk_kai.h" 昨天的epoll&#xff1a; 可恶抄错代码了 epoll_s.csockect return listenfdsetsockoptsockaddr_in bind listenfd & serveraddr…

Zilliz 推出 Spark Connector:简化非结构化数据处理流程

随着人工智能&#xff08;AI&#xff09;和深度学习&#xff08;Deep Learning&#xff09;技术的高速发展&#xff0c;使用神经网络模型将数据转化为 Embedding 向量 已成为处理非结构化数据并实现语义检索的首选方法&#xff0c;广泛应用于搜索、推荐系统等 AI 业务中。 以生…

Windows 11+Visual Studio 2022 环境OpenCV+CUDA 12.5安装及踩坑笔记

周六日在家捣腾了一下&#xff0c;把过程记录下来。 前置条件 Visual Studio C 生成工具和本机显卡适配的CUDA与CUDA匹配的cuDNNPython 3NumPyOpenCV源代码以及对应版本的OpenCV-contrib模块源码CMake Visual Studio 下载Visual Studio&#xff08;我本机的是VS2022&#xf…

虚拟局域网配置与分析-VLAN

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 一、相关知识 虚拟局域网&#xff08;Virtual Local Area Network&#xff0c;VLAN&#xff09;是一组逻辑上的设备和用户&#xff1b;不受物理位置的…

二、【Python】入门 - 【PyCharm】安装教程

往期博主文章分享文章&#xff1a; 【机器学习】专栏http://t.csdnimg.cn/sQBvw 目录 第一步&#xff1a;PyCharm下载 第二步&#xff1a;安装&#xff08;点击安装包打开下图页面&#xff09; 第三步&#xff1a;科学使用&#xff0c;请前往下载最新工具及教程&#xff1a…

前端:Vue学习-3

前端&#xff1a;Vue学习-3 1. 自定义指令2. 插槽2.1 插槽 - 后备内容&#xff08;默认值&#xff09;2.2 插槽 - 具名插槽2.3 插槽 - 作用域插槽 3. Vue - 路由3.1 路由模块封装3.2 声明式导航 router-link 高亮3.3 自定义匹配的类名3.4 声明式导肮 - 跳转传参3.5 Vue路由 - 重…

C#初级——条件判断语句和循环语句

条件判断语句 简单的条件判断语句&#xff0c;if()里面进行条件判断&#xff0c;如果条件判断正确就执行语句块1&#xff0c;如果不符合就执行语句块2。 if (条件判断) { 语句块1 } else { 语句块2 } int age 18;if (age < 18){Console.WriteLine("未…

Python面试宝典第18题:单词搜索

题目 给定一个m x n的二维字符网格board和一个字符串单词word。如果word存在于网格中&#xff0c;返回true。否则&#xff0c;返回false。单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构成。所谓相邻单元格&#xff0c;是那些水平相邻或垂直相邻的单元格。 备注&…

Blender材质-PBR与纹理材质

1.PBR PBR:Physically Based Rendering 基于物理的渲染 BRDF:Bidirection Reflectance Distribution Function 双向散射分散函数 材质着色操作如下图&#xff1a; 2.纹理材质 左上角&#xff1a;编辑器类型中选择&#xff0c;着色器编辑器 新建着色器 -> 新建纹理 -> 新…

爬虫学习3:爬虫的深度爬取

爬虫的深度爬取和爬取视频的方式 深度爬取豆瓣读书 import time import fake_useragent import requests from lxml import etree head {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 …

[AWS]MSK调用,报错Access denied

背景&#xff1a;首先MSK就是配置一个AWS的托管 kafka&#xff0c;创建完成之后就交给开发进行使用&#xff0c;开发通常是从代码中&#xff0c;编写AWS的access_key 和secret_key进行调用。 但是开发在进行调用的时候&#xff0c;一直报错连接失败&#xff0c;其实问题很简单&…

AI学习记录 - 本地知识库实现的相关知识

在公司内部实现了个知识库&#xff0c;由于保密吗&#xff0c;只介绍在实现知识库的过程中用到的知识&#xff08;虽然知识库也是个烂大街的东西了hehehehe&#xff09; 1、分词器 先分词&#xff0c;中文可以使用jieba分词 2、构造数据集 将词汇向量化是自然语言处理中的…

OpenHarmony 开发

本心、输入输出、结果 文章目录 OpenHarmony 开发前言JonathanOpenHarmony 并不是 AndroidOpenHarmony 应用迁移OpenHarmony 的开发流程OpenHarmony 开发 编辑 | 简简单单 Online zuozuo 地址 | https://blog.csdn.net/qq_15071263 如果觉得本文对你有帮助,欢迎点赞、收藏、评…