当前位置: 首页 > news >正文

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

在这里插入图片描述

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

文章目录

  • 一、this指针引入
    • 1.引入
    • 2.分析
    • 3.图示
  • 二、 this指针存在哪里?
  • 三、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指针,占用内存小并且需要频繁使用,所以,将它放到寄存器里能大大提升运行效率。

三、this指针的特性

  1. this指针的类型:类类型* const,即成员函数中,不能给this指针赋值。
  2. 只能在“成员函数”的内部使用
  3. this指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给
    this形参。所以对象中不存储this指针。
  4. this指针是“成员函数”第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传
    递,不需要用户传递

四、 案例分析

下面代码会出现问题吗?

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

前提知识

  • p的意义有两个。1.p是A类一个对象的指针,p->print(),对象的指针调用函数肯定是找成员函数中的,也就是说编译的时候检查语法,让我们知道print函数是A类中的成员函数,起到定位语法作用。

  • 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函数中使用了成员变量,编译时printA函数底层如下形式:

void PrintA(Data* this)
{
cout<<this_a<<endl;
}
mian函数中是
p->PrintA(p);

将p传给了this指针。
_a=>this_a,需要访问this指针,但此时this指针为空。
所以,运行崩溃!

相关文章:

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

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …...

系统讲解java中list.stream()的用法

在Java 8及以后的版本中&#xff0c;引入了新的Stream API&#xff0c;这个API提供了一组新的操作方法&#xff0c;可以便捷 地对Java集合进行过滤、映射、排序、分组等操作。 在Stream API中主要分中间操作&#xff0c;和终止操作 中间操作是对流进行处理但不产生最终结果的…...

字节面试:请说一下DDD的流程,用电商系统为场景

说在前面 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业字节、如阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格&#xff0c;遇到很多很重要的面试题&#xff1a; 谈谈你的DDD落地经验&#xff1f; 谈谈你对DDD的理解&…...

第26章_事务概述与隔离级别

文章目录 事务事务的特征事务的控制语句事务的生命周期事务的执行过程 ACID特性原子性一致性隔离性持久性 隔离级别不同隔离级别并发异常脏读不可重复读幻读区别 总结 事务 &#xff08;1&#xff09;事务的前提&#xff1a;并发连接访问。MySQL的事务就是将多条SQL语句作为整…...

合肥工业大学网络安全实验IP-Table

✅作者简介:CSDN内容合伙人、信息安全专业在校大学生🏆 🔥系列专栏 :hfut实验课设 📃新人博主 :欢迎点赞收藏关注,会回访! 💬舞台再大,你不上台,永远是个观众。平台再好,你不参与,永远是局外人。能力再大,你不行动,只能看别人成功!没有人会关心你付出过多少…...

Docker本地镜像发布到阿里云或私有库

本地镜像发布到阿里云流程 &#xff1a; 1.自己生成个要传的镜像 2.将本地镜像推送到阿里云: 阿里云开发者平台:开放云原生应用-云原生&#xff08;Cloud Native&#xff09;-云原生介绍 - 阿里云 2.1.创建仓库镜像&#xff1a; 2.1.1 选择控制台&#xff0c;进入容器镜像服…...

使用openvc进行人脸检测:Haar级联分类器

1 人脸检测介绍 1.1 什么是人脸检测 人脸检测的目标是确定图像或视频中是否存在人脸。如果存在多个面&#xff0c;则每个面都被一个边界框包围&#xff0c;因此我们知道这些面的位置 人脸检测算法的主要目标是准确有效地确定图像或视频中人脸的存在和位置。这些算法分析数据…...

Netty心跳检测

文章目录 一、网络连接假死现象二、服务器端的空闲检测三、客户端的心跳报文 客户端的心跳检测对于任何长连接的应用来说&#xff0c;都是一个非常基础的功能。要理解心跳的重要性&#xff0c;首先需要从网络连接假死的现象说起。 一、网络连接假死现象 什么是连接假死呢&…...

【leaflet】1. 初见

▒ 目录 ▒ &#x1f6eb; 导读需求开发环境 1️⃣ 概念概念解释特点 2️⃣ 学习路线图3️⃣ html示例&#x1f6ec; 文章小结&#x1f4d6; 参考资料 &#x1f6eb; 导读 需求 要做游戏地图了&#xff0c;看到大量产品都使用的leaflet&#xff0c;所以开始学习这个。 开发环境…...

数据结构与算法(Java版) | 详解十大经典排序算法之一:冒泡排序

前面虽然大家已经知道了多种不同的排序算法&#xff0c;但是我一直都没来得及给大家讲&#xff0c;所以&#xff0c;从这一讲起&#xff0c;我就要开始来给大家详细讲解具体的这些排序算法了。 下面&#xff0c;我们先来看第一个最常见的排序&#xff0c;即冒泡排序。 冒泡排…...

轻量封装WebGPU渲染系统示例<24>- Rendering Pass Graph基本用法(源码)

当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/feature/rendering/src/voxgpu/sample/PassNodeGraphTest.ts 此示例基于此渲染系统实现&#xff0c;当前示例TypeScript源码如下: class PassGraph extends WGRPassNodeGraph {constructor() { super();…...

开设自己的网站系类01购买服务器

开始建设自己的网站吧&#xff01; 编者买了一个服务器打算自己构建一个网站&#xff0c;用于记录生活。网站大概算是一个个人博客吧。记录创建过程的一些步骤 要开设自己的网站&#xff0c;需要执行以下关键步骤 以下只是初步列出了建立自己的网站的大概步骤&#xff0c;后…...

FTP、NFS、SAMBA系统服务一

一、rsync托管xinetd 1、为什么要进行服务托管 独立服务&#xff1a;独立启动脚本 ssh ftp nfs dns ... 依赖服务: 没有独立的启动脚本 rsync telnet 依赖xinetd服务&#xff08;独立服务&#xff09; 2、如何将rsync托管给xinetd服务去管理&#xff1f; 第一步&#xff1…...

transfomer模型——简介,代码实现,重要模块解读,源码,官方

一、什么是transfomer Transformer是一种基于注意力机制&#xff08;attention mechanism&#xff09;的神经网络架构&#xff0c;最初由Vaswani等人在论文《Attention Is All You Need》中提出。它在自然语言处理&#xff08;NLP&#xff09;领域取得了巨大成功&#xff0c;特…...

队列(Queue):先进先出(FIFO)的数据结构

队列是一种基本的数据结构&#xff0c;用于在计算机科学和编程中管理数据的存储和访问。队列遵循先进先出&#xff08;First In, First Out&#xff0c;FIFO&#xff09;原则&#xff0c;即最早入队的元素首先出队。这种数据结构模拟了物理世界中的队列&#xff0c;如排队等待服…...

吃透 Spring 系列—AOP部分

目录 ◆ AOP 简介 - AOP的概念 - AOP思想的实现方案 - 模拟AOP的基础代码 - AOP相关概念 ◆ 基于xml配置的AOP - xml方式AOP快速入门 - xml方式AOP配置详解 - xml方式AOP原理剖析 ◆ 基于注解配置的AOP - 注解方式AOP基本使用 - 注解方式AOP配置详解 - 注解…...

redis 问题解决 2

1.4 数据存储 1、Redis 的数据过期策略是什么? Redis的数据过期策略包括两种机制:被动删除和主动删除。 被动删除: 当某个键被访问时,如果发现这个键已经过期,Redis会立即删除这个键。这意味着如果一个过期的键从未被访问,它就不会被自动删除。这是一种惰性删除策略。主…...

Spring Boot 校验用户上传的图片文件

图片上传是现代应用中非常常见的一种功能&#xff0c;也是风险比较高的一个地方。恶意用户可能会上传一些病毒、木马。这些东西不仅严重威胁服务器的安全还浪费了带宽&#xff0c;磁盘等资源。所以&#xff0c;在图片上传的接口中&#xff0c;一定要对用户上传的文件进行严格的…...

【springboot配置项动态刷新】与【yaml文件转换为java对象】

文章目录 一&#xff0c;序言二&#xff0c;准备工作1. pom.xml引入组件2. 配置文件示例 三&#xff0c;自定义配置项动态刷新编码实现1. 定义自定义配置项对象2. 添加注解实现启动时自动注入3. 实现yml文件监听以及文件变化处理 四&#xff0c;yaml文件转换为java对象1. 无法使…...

JS移动端触屏事件

在我们PC端中有许多的事件&#xff0c;那我们在移动端有没有事件呢&#xff1f;让我为大家介绍一下移动端常用的事件&#xff0c;触屏事件 触屏事件 touch (也称触摸事件)&#xff0c;Android 和IOS 都有 touch 对象代表一个触摸点。触摸点可能是一根手指&#xff0c;也可能是一…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

XCTF-web-easyupload

试了试php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接&#xff0c;得到flag...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...