【C++】this指针讲解超详细!!!

在这里插入图片描述

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤
📃个人主页 :阿然成长日记 👈点击可跳转
📆 个人专栏: 🔹数据结构与算法🔹C语言进阶
🚩 不能则学,不知则问,耻于问人,决无长进
🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍

文章目录

  • 一、this指针引入
    • 1.引入
    • 2.分析
    • 3.图示
  • 二、 this指针存在哪里?
  • 三、 案例分析

一、this指针引入

1.引入

#include<iostream>
using namespace std;
class Data
{
public:void Init(int year,int month,int day){_year = year;_month = month;_day = day;}void print(){cout << _year << ":" << _month << ":" << _day << endl;}
private:int _year;int _month;int _day;
};int main()
{
//创建Data的对象1Data d1;d1.Init(1999, 1, 1);
//创建Data的对象2Data d2;d2.Init(2023, 1, 1);
//调用print函数d1.print();d2.print();return 0;
}

打印结果:
在这里插入图片描述

2.分析

上面代码运行结果中,为什么两个对象调用同一个函数能打印出不同的日期呢?或者说同一个函数如何做到结果不同呢?
简单说是通过C++的一个关键字this来实现的。
上面代码着编译后,就成了如下:

#include<iostream>
using namespace std;
class Data
{
public:void Init(int year,int month,int day){_year = year;_month = month;_day = day;}void print(Data* this){cout << this->_year << ":" << this->_month << ":" << this->_day << endl;}
private:int _year;int _month;int _day;
};int main()
{
//创建Data的对象1Data d1;d1.Init(1999, 1, 1);
//创建Data的对象2Data d2;d2.Init(2023, 1, 1);
//调用print函数d1.print(&d1);d2.print(&d2);return 0;
}

当不同对象调用print函数时,其实在底层是传了一个Data*类型的指针this。

void print(Data* this){cout << this->_year << ":" << this->_month << ":" << this->_day << endl;}

> 如下图所示:
其实底层还是和C语言函数调用一样,也需要传参,只不过C++的编译器为我们默默做了这些事情,让我们用起来更方便。但是,不能显示的去写出this的相关实参和形参,需要注意的是在类中可以使用this->。

3.图示

在这里插入图片描述

this本质是一个形参,哪个对象调用他,就指向哪个对象。

二、 this指针存在哪里?

下图是代码在vs2019编译器下执行的汇编语句
在这里插入图片描述
当执行d1.Init(1999, 1, 1);时,先是将三个实参进行压栈。其实实参应该有4个,还有一个隐藏的this指针
(1)000426EF push 1
(2)000426F1 push 1
(2)000426F3 push 7CFh
通过这一句(4)000426F8 lea ecx,[d1] 我们可以清晰的看到this指针在vs编译器下,是存到了寄存器( ecx)。
其实,this指针存在的位置一般是在栈帧上,不同的编译器有所不同,例如vs2019就是存在寄存器上。
因为this指针,占用内存小并且需要频繁使用,所以,将它放到寄存器里能大大提升运行效率。

三、 案例分析

下面代码会出现问题吗?

class A
{
public:
void Print()
{
cout << "Print()" << endl;
}
private:
int _a;
};
int main()
{
A* p = nullptr;
p->Print();
return 0;
}

前提知识

  • p指针为空,相当于this指针为空。
  • 成员变量存储在对象中
  • 成员函数没有存储在对象中
  • p->Print();说明调用的是A类中的成员函数

调用print函数与this指针无关,只有访问成员变量时才会使用到this。
因为函数是在编译链接的时候找的,上一篇详细讲过对象的存储方式中讲过,函数的调用是通过公共区域的函数表查找修饰后的函数名【因为C++支持重载,所以需要对函数名 进行特殊的修饰】来进行查找。

所以,代码运行正常。
看下面代码:

class A
{
public:
void PrintA()
{
cout<<_a<<endl;
}
private:
int _a;
};
int main()
{
A* p = nullptr;
p->PrintA();
return 0;
}

printA函数中使用了成员变量,需要使用this指针,但此时this指针为空。
所以,运行崩溃!

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

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

相关文章

ElasticSearch的集群、节点、索引、分片和副本

Elasticsearch是面向文档型数据库&#xff0c;一条数据在这里就是一个文档。为了方便大家理解&#xff0c;我们将Elasticsearch里存储文档数据和关系型数据库MySQL存储数据的概念进行一个类比 ES里的Index可以看做一个库&#xff0c;而Types相当于表&#xff0c;Documents则相当…

宠物社区系统宠物领养小程序,宠物救助小程序系统多少钱?

当前很多的宠物被抛弃和虐杀&#xff0c;它们没有选择权&#xff0c;我们强制性的把狗带进人类的生活中&#xff0c;然后又无情的抛弃&#xff0c;让它们无家可归&#xff0c;变成流浪狗&#xff0c;它们做错了什么&#xff1f;流浪动物被主人遗弃之后居无定所&#xff0c;时刻…

海康工业相机如何提高相机帧率

影响帧率的因素 相机参数 帧率限制使能 像素格式 曝光时间 数据包大小&#xff08;网口&#xff09; 相机默认参数 ADC位深 系统环境设置

相机内外参实践之点云投影矢量图

目录 概述 涉及到的坐标变换 深度值可视化 3D点云的2D投影实现 实现效果 参考文献 概述 Camer的内外参在多模态融合中主要涉及到坐标系变换&#xff0c;即像素坐标、相机坐标以及其他坐标系。这篇就针对点云到图像的投影与反投影做代码实践&#xff0c;来构建一张具有深度…

阿里云-maven私服idea访问私服与组件上传

1.进入aliyun制品仓库 2. 点击 生产库-release进入 根据以上步骤修改本地 m2/setting.xml文件 3.pom.xml文件 点击设置获取url 4. idea发布组件

【JAVA学习笔记】 68 - 网络——TCP编程、UDP编程

项目代码 https://github.com/yinhai1114/Java_Learning_Code/tree/main/IDEA_Chapter21/src 网络 一、网络相关概念 1.网络通讯 1.概念:两台设备之间通过网络实现数据传输 2.网络通信:将数据通过网络从一台设备传输到另一台设备 3. java.net包下提供了一系列的类或接口&a…

NFS文件系统共享服务器实战

架设一台NFS服务器&#xff0c;并按照以下要求配置 准备 两台Linux虚拟机一台作为服务端server&#xff0c;一台作为客户端client server IPV4&#xff1a;192.168.110.136/24 client IPV4&#xff1a;192.168.110.134/24 两台服务器都需要关闭防火墙和seLinux 服…

优化编辑距离以测量文本相似度

一、说明 编辑距离是一种文本相似度度量&#xff0c;用于测量 2 个单词之间的距离。它有许多方面应用&#xff0c;如文本自动完成和自动更正。 对于这两种用例中的任何一种&#xff0c;系统都会将用户输入的单词与字典中的单词进行比较&#xff0c;以找到最接近的匹配项&#x…

智慧城市数据中台建设方案:PPT全文51页,附下载

关键词&#xff1a;智慧城市解决方案&#xff0c;数据中台解决方案&#xff0c;智慧城市建设&#xff0c;数据中台技术架构&#xff0c;数据中台建设 一、智慧城市数据中台建设背景 智慧城市数据中台是在城市数字化转型和智能化升级的背景下提出的&#xff0c;旨在实现城市数…

Visual Studio 2019下编译OpenCV 4.7 与OpenCV 4.7 contrib

一、环境 使用的环境是Win10,Visual Studio 2019,Cmake3.28,cdua 11.7&#xff0c;cudnn 8.5,如果只是在CPU环境下使用&#xff0c;则不用安装CUDA。要使用GPU处理&#xff0c;安装好CUDA之后&#xff0c;要测试安装的CUDA是否能用。不能正常使用的话&#xff0c;添加一下系统…

Mac安装与配置eclipse

目录 一、安装Java&#xff1a;Mac环境配置&#xff08;Java&#xff09;----使用bash_profile进行配置&#xff08;附下载地址&#xff09; 二、下载和安装eclipse 1、进入eclipse的官网 (1)、点击“Download Packages ”​编辑 (2)、找到macOS选择符合自己电脑的框架选项…

一步一步详细介绍如何使用 OpenCV 制作低成本立体相机

在这篇文章中,我们将学习如何创建定制的低成本立体相机(使用一对网络摄像头)并使用 OpenCV 捕获 3D 视频。我们提供 Python 和 C++ 代码。文末并附完整的免费代码下载链接 我们都喜欢观看上面所示的 3D 电影和视频。您需要如图 1 所示的红青色 3D 眼镜才能体验 3D 效果。它是…

kubeadm部署k8s及高可用

目录 CNI 网络组件 1、flannel的功能 2、flannel的三种模式 3、flannel的UDP模式工作原理 4、flannel的VXLAN模式工作原理 5、Calico主要组成部分 6、calico的IPIP模式工作原理 7、calico的BGP模式工作原理 8、flannel 和 calico 的区别 Kubeadm部署k8s及高可用 1、…

API SIX系列-服务搭建(一)

APIsix简介 APISIX是一个微服务API网关&#xff0c;具有高性能、可扩展性等优点。它基于nginx&#xff08;openresty&#xff09;、Lua、etcd实现功能&#xff0c;借鉴了Kong的思路。和传统的API网关相比&#xff0c;APISIX具有较高的性能和较低的资源消耗&#xff0c;并且具有…

react类式组件的生命周期和useEffect实现函数组件生命周期

概念 生命周期是一个组件丛创建,渲染,更新,卸载的过程,无论是vue还是react都具有这个设计概念,也是开发者必须熟练运用的,特别是业务开发,不同的生命周期做不同的事是很重要的. ....多说两句心得,本人是先接触vue的,无论是vue2还是vue3的生命周期,在理解和学习上都会比react更…

嵌入式养成计划-52----ARM--开发板介绍--相关硬件基础内容介绍--GPIO讲解

一百三十一、开发板介绍 131.1 核心板介绍 131.2 拓展板 一百三十二、相关硬件基础内容介绍 132.1 PCB PCB&#xff08; Printed Circuit Board&#xff09;&#xff0c;中文名称为印制电路板&#xff0c;又称印刷线路板&#xff0c; 是重要的电子部件&#xff0c;是电子元器…

Linux常用命令——bzless命令

在线Linux命令查询工具 bzless 增强.bz2压缩包查看器 补充说明 bzless命令是增强“.bz2”压缩包查看器&#xff0c;bzless比bzmore命令功能更加强大。 语法 bzless(参数)参数 文件&#xff1a;指定要分屏显示的.bz2压缩包。 在线Linux命令查询工具

计算机毕业设计 基于Springboot的影院购票管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

网络运维Day10

文章目录 SHELL基础查看有哪些解释器使用usermod修改用户解释器BASH基本特性 shell脚本的设计与运行编写问世脚本脚本格式规范执行shell脚本方法一方法二实验 变量自定义变量环境变量位置变量案例 预定义变量 变量的扩展运用多种引号的区别双引号的应用单引号的应用反撇号或$()…

【机器学习范式】监督学习,无监督学习,强化学习, 半监督学习,自监督学习,迁移学习,对比分析+详解与示例代码

目录 1. 监督学习 (Supervised Learning): 2. 无监督学习 (Unsupervised Learning): 3. 强化学习 (Reinforcement Learning): 4. 半监督学习 (Semi-Supervised Learning): 5. 自监督学习 (Self-Supervised Learning): 6. 迁移学习 (Transfer Learning): 7 机器学习范式应…