操作符“->“


title: 操作符"->"
date: 2024-01-16 00:00:00
categories:

  • C++
  • 箭头
    tags: 箭头操作以及偏移量计算 #嘎嘎

操作符"->"

->是一个成员访问的操作,它的作用是通过一个指针来访问它所指向的对象的成员变量或成员函数。它的左边必须是一个指针,右边必须是一个成员的名字。它的含义是,先解引用左边的指针,得到它所指向的对象,然后访问这个对象的右边的成员。也没什么。

".“和”->"的区别

创建个类先

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

对象要调用Print方法就是e.Print(); 或ptr->Print(); 这两个对象一个是Entity,一个是Entity* 。

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

	Entity* ptr=new Entity();
	

	
	ptr->Print();//相当于(*ptr).Print();

	ptr->x = 2;//这样访问成员变量
}

在C++中,.-> 都是用来访问结构体或类的成员的运算符,但它们的使用场景不同。

  • . 运算符用于访问一个实际对象的成员。例如,如果你有一个 Vector3 类型的对象 vec,你可以使用 vec.x 来访问它的 x 成员。
  • -> 运算符用于通过指针访问对象的成员。如果你有一个指向 Vector3 对象的指针 ptr,你可以使用 ptr->x 来访问它指向的对象的 x 成员。

简单来说,当你有一个对象时,你使用 . 来访问它的成员;当你有一个指向对象的指针时,你使用 -> 来访问它指向的对象的成员。这是因为指针需要被解引用(dereferenced)来访问指向的对象,而 -> 运算符自动为你做了这个操作。

也可以这么操作:

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

我是看图里这么理解,Entity e;e就是这个内存空间的整体想要访问哪个成员就直接用"."调出来,但如果是Entity* ptr,ptr是个指针,所以要访问成员就需要指向它,所以用->

在这里插入图片描述

重载"->"

什么时候需要重载箭头呢,看例子,在之前实现智能指针的时候有个例子:

class ScopedPtr
{
private:
	Entity* m_Obj;
public:
	ScopedPtr(Entity* entity)
		:m_Obj(entity){}
	
    ~ScopedPtr()
	{
		delete m_Obj;
	}
	Entity* GetObj()
	{
		return m_Obj;
	}

};

简单的实现了智能指针,能自动delete,并且可以通过GetObj()得到私有成员变量.如果我们使用这个ScopedPtr,const ScopedPtr entity = new Entity();就会发现想要调用Entity的Print方法就得通过

entity.GetObj()->Print(); entity.GetObj()->Print();//entity.GetObj()得到了Entity*类型的m_Obj,就可以通过->来访问Print

这未免长了点,而且不够简洁干净,所以我们就可以在ScopedPtr中重载这个运算符

const Entity* operator->()const
	{
		return m_Obj;
	}

这个重载操作符是为了实现指针类的功能,让它可以像指针一样使用 -> 运算符来访问指向的对象的成员。定义为 Entity* 是为了返回一个 Entity 类型的指针,这样就可以使用 -> 运算符来链式访问 Entity 的成员

现在我们就可以写成entity->Print();来打印Hello

重载详见:

Operator(操作符)| HahのBlog (rhahr.top)

计算变量偏移量

这是一种编程技巧,请看代码:

struct Vector3
{
	float x, y, z;
};

int main()
{
	int offset=(int)&((Vector3*)nullptr)->y;

	std::cout << offset << std::endl;
	
	std::cin.get();
}

这行代码(int)&((Vector3*)nullptr)->y;中

  • nullptr表示一个空指针,强转只转换类型而不改变值,(Vector3*)nullptr 将 nullptr 转换为 Vector3 类型的指针,表示一个空的 Vector3 对象的地址
  • 然后类型转换成Vector3类型的空指针,然后用->访问y,这里的指针实际上是空的,->y 尝试访问这个空对象的 y 成员,但实际上不会访问任何内存地址,而是返回 y 成员相对于结构体起始位置的偏移量。
  • (int)&将这个偏移量的地址转换为整数类型,得到 y 成员的偏移量。

float是4字节大小,所以x,y,z 偏移量为0,4,8 如果结构体中定义时交换y与z,也就是float x,z,y;那么y的偏移量就是8

困惑点:

  • nullptr是个空指针,空指针是一个特殊的指针值,通常用 nullptr(在C++11及以后的版本中)或 NULL(在旧的C++标准中)来表示。空指针没有指向任何有效的内存地址,它的目的是表示一个明确的“无指向”的状态。在代码中,空指针通常用于初始化指针变量,或者在某些操作后将指针设置为一个安全的值,以避免未定义行为。
  • 这不同于野指针,野指针是指向未知内存地址或已经释放的内存的指针。野指针的危险在于,它可能指向任意的内存位置,这可能导致程序崩溃或数据损坏。野指针通常是由于指针变量没有被正确初始化,或者在释放了动态分配的内存后没有将指针设置为 nullptr 而产生的。

这里还涉及内存对齐和字节填充,见文章

内存对齐与填充字节| HahのBlog (rhahr.top)

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

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

相关文章

(vue)eslint-plugin-vue版本问题 安装axios时npm ERR! code ERESOLVE

(vue)eslint-plugin-vue版本问题 安装axios时npm ERR! code ERESOLVE 解决方法&#xff1a;在命令后面加上 -legacy-peer-deps结果&#xff1a; 解决参考&#xff1a;https://blog.csdn.net/qq_43799531/article/details/131403987

全网最适合入门的面向对象编程教程:09 类和对象的Python实现-类之间的关系,你知道多少?

全网最适合入门的面向对象编程教程&#xff1a;09 类和对象的 Python 实现-类之间的关系&#xff0c;你知道多少&#xff1f; 摘要&#xff1a; 本文主要对类之间的关系进行了基本介绍&#xff0c;包括继承、组合、依赖关系&#xff0c;并辅以现实中的例子加以讲解&#xff0…

Java的进程和线程

一Java的进程 二Java的线程 多线程 ◆如果在一个进程中同时运行了多个线程&#xff0c;用来完成不同的工作&#xff0c;则称之为“多线程”。 ◆多个线程交替占用CPU资源&#xff0c;而非真正的并行执行。 ◆多线程好处。 ◆充分利用CPU的资源。 ◆简化编程模型。 ◆良好的用…

js 递归调用 相同对象--数组递归调用

<div class="save-cl"> <a-button @click="saveCl" >保存为常用策略</a-button> </div> saveCl(){ console.log(this.form.filterList[0],--------常用策略)// 此对象为上图对象 console.log(this.allElementsHaveValue(thi…

AGI系列(7)Reflection 在 AI agent 中的应用实例

斯坦福大学教授吴恩达一直非常推崇AI Agent,之前他提出过AI Agent的四种工作模式,分别是Reflection(反思)、Tool use(工具使用)、Planning(规划)和Multi-agent collaboration(多智能体协同)。 近日,他又开源了一个翻译 AI Agent, 他认为 AI 智能体机器翻译对改进传…

阿里巴巴Arthas分析调优JVM实战及常量池详解

目录 一、阿里巴巴Arthas详解 Arthas使用场景 Arthas命令 Arthas使用 二、GC日志详解 如何分析GC日志 CMS G1 GC日志分析工具 三、JVM参数汇总查看命令 四、Class常量池与运行时常量池 字面量 符号引用 五、字符串常量池 字符串常量池的设计思想 三种字符串操作…

掌握电路交换与分组交换:计算机网络的核心技术

计算机网络是现代信息社会的基石&#xff0c;而交换技术是实现网络通信的核心。本文将详细介绍两种典型的交换方式&#xff1a;电路交换和分组交换&#xff0c;帮助基础小白快速掌握这两种技术的基本概念和区别。 什么是电路交换&#xff1f; 电路交换&#xff08;Circuit Swi…

技术革新引领钢材质量智能化检测新纪元,基于YOLOv5全系列【n/s/m/l/x】参数模型开发构建钢材工业生产场景下钢材缺陷智能检测识别系统

随着人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;其应用领域不断拓宽&#xff0c;正深刻改变着传统产业的运作模式。在钢材生产这一基础工业领域&#xff0c;AI的引入正为钢材的质量检测带来革命性的变革。 在传统的钢材生产流程中&#xff0c;质量检测是确…

【C++】二叉搜索树的模拟实现

前言&#xff1a;今天我们学习相对来说比前面轻松一点的内容&#xff0c;二叉搜索树&#xff0c;在之前我们学习过二叉树今天的内容对于我们就会比较简单一点了&#xff0c;一起加油。 &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f449; 专栏分类:高质…

从零开始学量化~Ptrade使用教程——安装与登录

PTrade交易系统是一款高净值和机构投资者专业投资软件&#xff0c;为用户提供普通交易、篮子交易、日内回转交易、算法交易、量化投研/回测/实盘等各种交易工具&#xff0c;满足用户的各种交易需求和交易场景&#xff0c;帮助用户提高交易效率。 运行环境及安装 操作系统&…

计算机的错误计算(二十一)

摘要 两个不相等数相减&#xff0c;差为0&#xff1a; ? 在计算机的错误计算&#xff08;十九&#xff09;中&#xff0c;高中生小明发现本应为0的算式结果不为0. 今天他又发现对本不为0的算式&#xff0c;计算机的输出为0. 在 Python 中计算 &#xff1a; 则输出为0. 若用 C…

必备的 Adobe XD 辅助工具

想要高效便捷的使用 Adobe XD&#xff0c; Adobe XD 插件是必不可少的&#xff0c; Adobe XD 的插件非常多&#xff0c;但 90%都是英文&#xff0c;并且良莠不齐。在这儿挑选 9 个好用的 Adobe XD 插件给大家&#xff0c;这里是我整理的一些实用 Adobe XD 插件&#xff0c;让你…

3-2 梯度与反向传播

3-2 梯度与反向传播 主目录点这里 梯度的含义 可以看到红色区域的变化率较大&#xff0c;梯度较大&#xff1b;绿色区域的变化率较小&#xff0c;梯度较小。 在二维情况下&#xff0c;梯度向量的方向指向函数增长最快的方向&#xff0c;而其大小表示增长的速率。 梯度的计算 …

UE5 07-给物体添加一个拖尾粒子

添加一个(旧版粒子系统)cascade粒子系统组件 ,在模板中选择一个开发学习初始包里的粒子

Elasticsearch:Ingest architectures - 摄取架构

我们提供各种采集架构&#xff0c;以满足各种用例和网络配置的需求。 要将数据采集到 Elasticsearch&#xff0c;请使用最符合你的需求和用例的选项。对于许多用户和用例来说&#xff0c;最简单的方法是使用 Elastic Agent 采集数据并将其发送到 Elasticsearch。Elastic Agent…

Mybatis框架的集成使用

1_框架概述 框架是一个半成品&#xff0c;已经对基础的代码进行了封装并提供相应的API&#xff0c;开发者在使用框架时直接调用封装好的api可以省去很多代码编写&#xff0c;从而提高工作效率和开发速度,框架是一种经过校验、具有一定功能的半成品软件. 经过校验&#xff1a;指…

零基础学习MySQL---库的相关操作

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C从入门到精通》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、创建数据库 1.语法 CREATE DATABASE [IF NOT EXISTS] db_name [create_specification [, create_specification] .…

使用selenium定位input标签下的下拉框

先来看一下页面效果&#xff1a;是一个可输入的下拉列表 再来看一下下拉框的实现方式&#xff1a; 是用<ul>和<li>方式来实现的下拉框&#xff0c;不是select类型的&#xff0c;所以不能用传统的select定位方法。 在着手定位元素前一定一定要先弄清楚下拉列表…

CocoaPodsCmake

https://juejin.cn/post/7257048145233838141?searchId20240531171431E5868B41DC7B7016CCBA https://guides.cocoapods.org CocoaPods CocoaPods的作用 帮助程序员通过命令管理第三方库及更新&#xff0c;以达到扩展项目的目的。 CocoaPods的使用 在已有的工程目录下新增…

JAVA:文件防重设计指南

1、简述 在现代应用程序中&#xff0c;处理文件上传是一个常见的需求。为了保证文件存储的高效性和一致性&#xff0c;避免重复存储相同的文件是一个重要的优化点。本文将介绍一种基于哈希值的文件防重设计&#xff0c;并详细列出实现步骤。 2、设计原理 文件防重的基本思路…