【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 类的对象可以方便地进行增加和减少操作。

总结

        运算符重载是一种强大的编程技术,允许用户定义的类型通过标准运算符执行自定义的操作。通过运算符重载,代码变得更加直观,可读性提高,使得类和对象的使用更加自然。在实际应用中,运算符重载常用于数学计算、矩阵操作等领域,提高了代码的灵活性和可维护性

如果觉得这篇博客对你有帮助,可以点点关注哟,留下你们的点赞评论收藏,你们的关注与点赞就是我最大的鼓励~~😉😉我会持续创作滴!小海在这里谢谢各位~~

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

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

相关文章

金蝶Apusic应用服务器 loadTree JNDI注入漏洞复现(QVD-2023-48297)

0x01 产品简介 金蝶Apusic应用服务器是一款企业级应用服务器,支持Java EE技术,适用于各种商业环境。 0x02 漏洞概述 由于金蝶Apusic应用服务器权限验证不当,导致攻击者可以向loadTree接口执行JNDI注入,造成远程代码执行漏洞。利用该漏洞需低版本JDK。(漏洞比较旧,8月份…

Java中如何优雅的根治null值引起的Bug问题

1. Java对象为null会引发的问题 NullPointerException&#xff1a;当你尝试调用或访问一个null对象的属性或方法时&#xff0c;Java会抛出NullPointerException异常。例如&#xff0c;如果你有一个名为person的变量&#xff0c;它被设置为null&#xff0c;然后你尝试调用perso…

测试框架|Burp Suite几个基本工具的使用

前阵子项目上想通过测试工具在网页上模拟返回错误代码 500 来查看页面的错误处理&#xff0c;然后去调查了下 burp suite&#xff0c;看了些基本工具的使用文档。虽然最后证实 burp suite 只能用来处理页面测试应用程序的实际行为和响应&#xff0c;而不是尝试模拟不存在的问题…

springboot学习笔记(五)

MybatisPlus进阶 1.MybatisPlus一对多查询 2.分页查询 1.MybatisPlus一对多查询 场景&#xff1a;我有一个表&#xff0c;里面填写的是用户的个人信息&#xff08;姓名&#xff0c;生日&#xff0c;密码&#xff0c;用户ID&#xff09;。我还有一个表填写的订单信息&#x…

4 postman响应数据解析

上一篇:3 使用postman批量创建测试数据-CSDN博客 在接口测试中,从接口的响应结果中获取数据是很常用的。比如说做断言的时候,需要确保接口返回数据是符合预期的。又比如有些接口的输入参数值,需要用到前面接口运行返回的数据。下面先介绍如何解析响应数据(以json数…

持续集成交付CICD:GitLabCI 封装Python类 并结合 ArgoCD 完成前端项目应用发布

目录 一、实验 1. 环境 2. Python代码实现获取文件 3.Python代码实现创建文件 4.Python代码实现更新文件 5.GitLab更新库文件与运行流水线 6.ArgoCD 完成前端项目应用发布 二、问题 1.Python获取GitLab指定仓库文件报错 2. K8S master节点运行Python代码报错 一、实验…

小程序分享携带参数,被覆盖问题

场景&#xff1a; 子组件中写了‘onShareAppMessage’和‘onShareTimeLine’&#xff0c;父组件中也写了这两个函数&#xff0c;并且在url中携带了参数&#xff0c;发现分享后在分享页‘onLoad’中取不到参数。 // 分享目标页 onLoad(async (props: any) > {const { share…

Java日志框架Logback

logback.xml文件配置(放在src下微服务建议放在resources下) <?xml version"1.0" encoding"UTF-8"?> <configuration><!--定义日志文件的存储地址,使用绝对路径--><property name"LOG_HOME" value"d:/logs"/>…

文件上传——后端

文件上传流程&#xff1a; 创建阿里云OSS&#xff08;对象存储服务&#xff09;的bucket 登录阿里云&#xff0c;并完成实名认证&#xff0c;地址&#xff1a;https://www.aliyun.com/. 可以通过搜索&#xff0c;进入以下页面&#xff1a; 点击立即使用后&#xff1a; 点击…

Goby 漏洞发布| 金蝶 EAS createDataSource 路径 jndiName 参数远程代码执行漏洞

漏洞名称&#xff1a;Apusic 应用服务器 createDataSource 远程代码执行漏洞 English Name&#xff1a;Kingdee EAS createDataSource path jndiName parameter remote code execution vulnerability CVSS core: 9.8 影响资产数&#xff1a; 26513 漏洞描述&#xff1a; 金…

[Linux] MySQL数据表(数据结构)管理

一、数据库 1.1 数据库的基本概念 数据库&#xff08;database&#xff09;是用来组织、存储和管理数据的仓库 数据库管理系统&#xff08;DBMS&#xff09;&#xff1a;是实现对数据有效组织&#xff0c;管理和存取的系统软件。 数据的建立和维护功能&#xff0c;数据定义…

重温经典struts1之自定义类型转换器及注册的两种方式(Servlet,PlugIn)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 前言 Struts的ActionServlet接收用户在浏览器发送的请求&#xff0c;并将用户输入的数据&#xff0c;按照FormBean中定义的数据类型&#xff0c;赋值给FormBean中每个变量&a…

java多线程创建的三种方式

第一种 第二种 第三种&#xff08;想获得线程的执行结果&#xff0c;建议使用这种&#xff09;

STM32的以太网外设+PHY(LAN8720)使用详解(3):PHY寄存器详解

0 工具准备 1.野火 stm32f407霸天虎开发板 2.LAN8720数据手册 3.STM32F4xx中文参考手册1 PHY寄存器 前面介绍到&#xff0c;站管理接口&#xff08;SMI&#xff09;允许应用程序通过2线时钟和数据线访问任意PHY寄存器&#xff0c;同时该接口支持访问最多32个PHY&#xff0c;也…

口碑好的国产主食冻干猫粮品牌有哪些?盘点十大放心猫粮国产名单

冻干猫粮可以帮助猫咪摄入更多的水分&#xff0c;因为冻干是高蛋白质的食物&#xff0c;当猫咪吃了冻干猫粮后&#xff0c;会感到口渴&#xff0c;从而更主动地去喝水。对于那些不喜欢喝水的猫咪&#xff0c;可以将冻干复水后再喂给它们&#xff0c;这样也可以增加猫咪的水分摄…

【toolschain algorithm cpp ros】cpp工厂模式实现--后续填充具体规划算法,控制器版的已填充了算法接入了仿真器

写在前面 现在局势危机&#xff0c;于是想复习一下之前写的设计模式&#xff0c;之前提到&#xff0c;做过一个闭环仿真器&#xff08;借用ros&#xff09;&#xff0c;见https://blog.csdn.net/weixin_46479223/article/details/134864123我的控制器的建立遵循了工厂模式&…

这样使用云渲染又快又省钱

我们都知道使用云渲染是要钱的&#xff0c;而且渲染的时间越久&#xff0c;需要的渲染费越多&#xff0c;哪么如何又快又省钱的拿到效果图呢&#xff1f;用炫云的渲染质量&#xff0c;保准让你使用云渲染渲染效果图又快又省钱。 我们使用炫云的时候&#xff0c;根据自己的需求…

Java自动化测试系列[v1.0.0][常见页面操作处理]

[控制滚动] package util; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement;public class ScrollBarUtil {/*** 控制滚动条向下拉到底* param driver 浏览器驱动*/public static void toBottom…

houdini 常用节点

雾化 撒点 减面 点连线 trace 节点 labs skelete 图片转模型 齿轮制作 polyextrude point to point connect primuv

sqli-labs第二十九三十

Less-29&#xff08;GET - Error based - IMPIDENCE MISMATCH - Having a WAF in front of web application) 手工注入 正常注入的时候发现 此处似乎没有sql注入 但是我上一个说了这个是有waf的 http://192.168.21.149/Less-29/?id1&id0‘union select 1,2,3-- 这里其…