P29 C++箭头运算符以及它对于结构体与类的指针关系

本期的主要内容是箭头运算符以及它对于结构体与类的指针可以做什么,最后实现我们自己的运算符重载。

01 为什么要使用运算符重载

从开发的角度而言,运算符重载的存在是为了提高开发效率,增加代码的可复用性,很多时候简化了代码

C++强大的原因之一是支持泛型编程。泛型编程使得算法可以独立于数据类型存在。自定义的数据类型通过操作符重载具有了和内建类型同样的使用接口,然后C++的模板加持下,你的算法可以利用这种接口一致性,实现泛化。

1.1 如何使用运算符重载

这是一个基本的 Entity 类,有一个输出提示语的 Print 函数。

#include <iostream>
#include <string>

class Entity
{
public:
    void Print() const { std::cout << "Hello!" << std::endl; }
};

int main()
{
    std::cin.get();
}

如果按照正常的使用方法,我们会这样创建对象。

int main()
{
    Entity e;
    e.Print();

    std::cin.get();
}

可如果是在堆上创建的,或者出于某种原因,程序中有一个指向它的指针,为了调用 Print 函数,该怎么办呢?这个时候就不能使用 . 了,下面的写法很明显是错的。

int main()
{
    Entity e;
    e.Print();

    Entity* ptr = &e;
    ptr.Print();

    std::cin.get();
}

因为 ptr 只是一个指针,也就是一个数值,不是对象,无法调用方法。

我们可以使用逆向引用 ptr 来实现调用 Print 函数(使用括号是因为符号的优先级的原因)。

int main()
{
    Entity e;
    e.Print();

    Entity* ptr = &e;
    (*ptr).Print();

    std::cin.get();

这样写当然没有问题,但它看起里有点笨重。

我们可以使用箭头运算符来简化这个操作。

int main()
{
    Entity e;
    e.Print();

    Entity* ptr = &e;
    ptr->Print();

    std::cin.get();
}

这样的操作就相当于逆向引用了 Entity 指针。

这就是它的全部内容了。

它只是一个快捷方式,成员变量也是同样的道理。

箭头运算符作为一个操作符,我们实际上可以重载它,并在你自定义类中使用它。

我们一起来看一个例子,来说明为什么要这么做以及怎么做。

假设我正在写一个智能指针的类,如下所示。

class ScopePtr
{
private:
    Entity* m_Obj;
public:
    ScopePtr(Entity* entity)
        :m_Obj(entity)
    {

    }
    ~ScopePtr()
    {
        delete m_Obj;
    }
};

这是一个基本的 ScopePtr 类,当 Entity 超出范围时,这个类会自动删除它。

我可以这样使用它。

int main()
{
    ScopePtr entity = new Entity();

    std::cin.get();
}

我希望能够调用 Print 函数,该怎么做呢?

首先我不能用 . 符号,但我可以将 m_Obj 变成 public 的,或者写一个 GetObject 函数,返回一个 Entity 指针,类似下面这样写法。

int main()
{
    ScopePtr entity = new Entity();
    entity.GetObject()->Print();

    std::cin.get();
}

不过这方法看起来太乱了,我希望能够使用堆分配的 Entity 一样使用它,类似于下面这样用法。

int main()
{
    ScopePtr* entity = new Entity();
    entity->Print();

    std::cin.get();
}

这就是我们想要重载箭头运算符的原因。

重载箭头运算符。

总结

良好的重载除了提高写代码的效率,也往往降低了代码维护的成本,更容易减少bug,提高代码质量,增加可读性。

如果非要说带来了什么负面影响,我觉得往往还是人为的原因。没有做好抽象导致滥用运算符重载。如果设计不好接口的话,还是不要强行引入运算符重载,这样可能反而降低代码可读性,增加耦合。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Django二转Day03 04

0 cbv执行流程&#xff0c;self问题 path(index/, Myview.as_view()),Myview.as_view() 实例化后返回 变成return Myview.dispatch(request, *args, **kwargs)但是视图函数Myview中没有 dispatch 方法 所以去 父类View中寻找return View.dispatch(request, *args, **kwargs)调用…

Apache Hive3.1.3 遇到DATE_FORMAT转换2021年12月格式的问题

比如&#xff1a;需要将时间2021-12-28 00:00:00转换成2021-12的格式&#xff0c;用date_format会将2021-12转换成2022-12的问题。 解决方法&#xff1a; 方式一&#xff1a;大写的‘Y’换成‘y’ 方式二&#xff1a;字符串截取&#xff0c;substr 本博主推荐方式一&#xf…

从谷歌搜索结果出现 AI 生成的图片谈起:AI的利与弊

随着人工智能&#xff08;AI&#xff09;的不断发展&#xff0c;其应用领域也越来越广泛。谷歌搜索是现代人日常生活中的一个常用工具&#xff0c;经常用于获取各种信息。最近&#xff0c;谷歌搜索结果中甚至出现了由AI生成的图片&#xff0c;这引发了人们对AI技术的讨论。 首…

SQL 数据操作技巧:SELECT INTO、INSERT INTO SELECT 和 CASE 语句详解

SQL SELECT INTO 语句 SELECT INTO 语句将数据从一个表复制到一个新表中。 SELECT INTO 语法 将所有列复制到新表中&#xff1a; SELECT * INTO newtable [IN externaldb] FROM oldtable WHERE condition;只复制一些列到新表中&#xff1a; SELECT column1, column2, colu…

如何写好开发信标题?推荐的营销邮件主题?

打开率高的开发信标题有哪些&#xff1f;怎么写吸引人邮件标题&#xff1f; 开发信标题是您的邮件首次与受众接触的部分&#xff0c;因此&#xff0c;它必须引起他们的兴趣&#xff0c;激发他们打开邮件的欲望。蜂邮EDM将讨论如何写好开发信标题&#xff0c;以及一些成功的开发…

mysql:免费的GUI客户端工具推荐并介绍常用的操作

给大家推荐几个常用的 mysql 数据库客户端 sequel-pro sequel-ace 官网下载地址 免费 sequel-ace 可以理解为 Sequel Pro 的升级版&#xff0c;由于Sequel Pro官方不维护了&#xff0c;特别是对 MySQL 8.0 支持不好&#xff0c;所以现在由社区维护了新分支 sequel-ace&#x…

5年经验之谈 —— 接口测试主要测哪些方面?

当今互联网时代&#xff0c;接口测试已经成为软件测试的一个重要组成部分。接口测试是指对系统各个接口进行验证&#xff0c;确保接口的正确性、稳定性和安全性。接口测试是软件开发过程中不可缺少的环节&#xff0c;它旨在确保接口能够正常工作&#xff0c;并且满足所需要的规…

nvm下载node.js以及环境变量配置

文章目录 一.卸载node.js二.安装nvm以及nvm环境配置2.1 安装nvm2.2 nvm环境配置 三.node.js安装以及环境配置3.1 node.js安装3.2 node.js环境配置3.3 node.js的环境配置参考如下文章。 一.卸载node.js 找到自己对应的node.js文件所在路径&#xff0c;通过控制面板卸载node.js&…

阿里云Arthas使用——通过watch命令查看类的返回值 捞数据出来

前言 Arthas 是一款线上监控诊断产品&#xff0c;通过全局视角实时查看应用 load、内存、gc、线程的状态信息&#xff0c;并能在不修改应用代码的情况下&#xff0c;对业务问题进行诊断&#xff0c;包括查看方法调用的出入参、异常&#xff0c;监测方法执行耗时&#xff0c;类…

开发中遇到的问题 -- 回调解决应用端和服务端通信问题

前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神的孩子都在歌唱 这里写目录标题 一. 问题概述二. 代码展示2.1 公共服务端2.2 应用端 一. 问题概述 项目介绍&#xff1a;今天做项目的时候遇到了点…

C++学习专栏【基础知识2】C++数据类型

1、内置数据类型 基本内置类型 C为程序员提供了丰富的内置数据类型以及用户自定义数据类型。以下表格列出了七种基本的 C 数据类型 - 类型关键字布尔值bool字符char整数int浮点数float双精度浮点数double无值void宽字符wchar_t 基本类型中的几种可以使用一个或多个类型修饰符…

RabbitMQ登录控制台显示--你与此网站的连接不是私密连接

一、RabbitMQ默认账号 Note: The default administrator username and password are guest and guest. 注:默认管理员用户名和密码为guest和guest 二、自己修改过或者注册的情况 由于本人之前用过,注册过账号密码,在登录时,用户名账号有异常出现以下问题 解决方案: 因为我的rab…

使用easyExcel框架报错:服务器缺少字体

后台服务使用easyExcel框架生成表格&#xff0c;但是生成的时候报如下的错误&#xff1a; 这种报错其实就是部署服务的服务器缺少字体&#xff0c;正确的方法是安装字体。需要注意的是&#xff0c;测试环境服务器与生产环境服务器的在配置版本上可能存在差异&#xff0c;因此需…

Node.js+Express+Nodemon+Socket.IO构建Web实时通信

陈拓 2023/11/23-2023/11/27 1. 简介 Websocket WebSocket是一种在单个TCP连接上提供全双工通讯的协议。特别适合需要持续数据交换的服务&#xff0c;例如在线游戏、实时交易系统等。 Websocket与Ajax之间的区别 Ajax代表异步JavaScript和XML。它被用作一组Web开发技术&…

全汉电源SN生产日期解读

新买了一个全汉的电脑电源&#xff0c;SN&#xff1a;WZ3191900030&#xff0c;看了几次没想明白&#xff0c;最后估计SN是2023年19周这样来记录日期的。问了一下京东全汉客服&#xff0c;果然就是这样的。那大家如果在闲鱼上看到全汉电源&#xff0c;就知道它的生产日期了。

YOLOv8改进 | 2023 | 通过RFAConv重塑空间注意力(深度学习的前沿突破)

一、本文介绍 本文给大家带来的改进机制是RFAConv&#xff0c;全称为Receptive-Field Attention Convolution&#xff0c;是一种全新的空间注意力机制。与传统的空间注意力方法相比&#xff0c;RFAConv能够更有效地处理图像中的细节和复杂模式(适用于所有的检测对象都有一定的…

C语言——写一个简单函数,找两个数中最大者

#include <stdio.h>int max( int a, int b ) { return a>b ? a:b; }int main() { int a, b;printf("输入两个数:\n");scanf("%d %d", &a, &b);printf("max %d\n", max(a, b));return 0; }输出结果&#xff1a;

Python---文件

文件--- 内存中存放的数据在计算机关机后就会消失。要长久保存数据&#xff0c;就要使用硬盘、光盘、U 盘等设备。为了便于数据的管理和检索&#xff0c;引入了“文件”的概念。 一篇文章、一段视频、一个可执行程序&#xff0c;都可以被保存为一个文件&#xff0c;并赋予一个…

TiDB专题---1、TiDB简介和特性

什么是TiDB TiDB 是一个分布式 NewSQL 数据库&#xff0c;它支持水平弹性扩展、ACID 事务、标准 SQL、MySQL 语法和 MySQL 协议&#xff0c;具有数据强一致的高可用特性&#xff0c;是一个不仅适合 OLTP 场景还适合 OLAP 场景的混合数据库。 TiDB 是 PingCAP 公司自主设计、研发…

pycharm编译报错处理

1.c生成工具下载 https://visualstudio.microsoft.com/visual-cpp-build-tools/ 在这里插入图片描述 pip install pycocotools