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

一篇文章带你了解C++中隐含的this指针

文章目录

    • 一、this指针的引出
    • 二、this指针的特性
      • 【面试题】

一、this指针的引出

  • 我们先来定义一个日期类Date,下面这段代码执行的结果是什么呢?
class Date
{
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()
{Date d1, d2;d1.Init(2022, 5, 11);d2.Init(2022, 5, 12);d1.print();d2.print();return 0;
}
  • 可以看到分别打印出了两个日期,它是怎么知道改打印哪个的?

在这里插入图片描述

  • 我们来分析一下,先看一下汇编代码,看一看

在这里插入图片描述


  • 我们看到上面的代码是调用的同一个函数,那么编译器是如何知道那两个日期的?

  • 其实C++里有一个隐形this指针,在微软的官方文档也有说明

  • 在使用函数的时候其实里面传了一个地址,然后有一个隐的this指针来接收


原形是这样:

在这里插入图片描述

在这里插入图片描述

  • 那为什么这里报错了呢?
  • 因为不必要写,这个是隐含的~~,我们可以直接在类里面使用

二、this指针的特性

  • 刚刚上面也给你看了原形,细心的烙铁已经发现了,这个this指针是有一个const修饰的,而且这个const是在*的右边

在这里插入图片描述

  • 这里的const修饰,我在C语言的指针部分已经讲过了—>指针章节

  • 下面我们回忆一下~

在这里插入图片描述

  • 到这里就得出的this本身是不被修改的,但是做指向的值是可以被修改

  • 我们可以在类中打印一下this指针的地址,再打印一下d1和d2的地址,我们来看一下:

在这里插入图片描述

  • 得到结果就是this指针指向一个指向当前对象的指针

  • 我们还可以下面这样,是不会报错的,但是不能向上面直接在形参就写上

在这里插入图片描述

特点:

1、形参和实参的位置,我们不能显示写
2、函数内部可以使用


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

【面试题】

  1. this指针存在哪里?

a、堆 b、栈 c、静态区 d、常量区 e、对象里面

  • 首先排除e,因为我们知道,在算类里的对象的时候是没有算this指针的大小,所以排除e
  • C++的const变量不是在常量区,可以看到这两个地址是挨着的

在这里插入图片描述

  • 那么什么在常量区呢?是const修饰的值在常量区,这个指针变量在栈区,指向了这个常量区的字符串的首字符,所以d也就排除

在这里插入图片描述

  • c就更不可能了,static和全局的才在静态区

  • a也可以排除,因为malloc的才在堆,这里不是malloc,所以排除

  • 最后就是在栈上,因为是一个形参(有些编译比如vs可能会用寄存器存储)。不同的编译器放在不同的位置,可能是栈,也可能是寄存器,(VC++编译器是放在ECX中,其它编译器有可能不同,也就是成员函数的其它参数正常都是存放在栈中。而this指针参数则是存放在寄存器中。)

  • 打开汇编我们也可以看到这里的lea就是load effective address【加载有效地址】,是存在ecx的值加载到 [d1]

在这里插入图片描述

  1. this指针可以为空吗?

下面我们来看两道题来解决这个问题的答案~


第一道:下面程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行

class A
{
public:void Print(){cout << "Print()" << endl;}
private:int _a;
};
int main()
{A* p = nullptr;p->Print();return 0;
}
  • 已经完美运行了,因为我这里没有访问类里的对象,所以可以正常运行

在这里插入图片描述


第二道:下面程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行

class A
{
public:void PrintA(){cout << _a << endl;}
private:int _a;
};int main()
{A* p = nullptr;p->PrintA();return 0;
}
  • 这里引发了空指针,因为我需要打印这里的_a,就要找到那块空间

在这里插入图片描述

  • 也就可以写成这样,this指针是空指针,解引用就会报错

在这里插入图片描述

  • 所以this指针是可以为空的,只要在成员函数内部不访问其内容,程序可以正常执行的。

最后本篇文章介绍了C++中隐含的this指针,特性,看完希望你学有所成!!!

http://www.lryc.cn/news/288937.html

相关文章:

  • shardinig-JDBC二开-支持sharding-jdbc的配置文件接入到nacos
  • a-table自定义展开图标
  • Kubernetes Ingress暴露应用的工作流程
  • Redis应用(1)缓存(1.2)------Redis三种缓存问题
  • 安全 专题
  • 自然语言处理-文本对分类或回归
  • 以梦为码,CodeArts Snap 缩短我与算法的距离
  • SpringMVC-HttpMessageConverter 报文信息转化器
  • [AG32VF407]国产MCU+FPGA 使用I2C测试陀螺仪MPU6050
  • ES 可扩展、高可靠、使用场景等常见问题
  • <网络安全>《4 网络安全产品之web应用防护系统》
  • 如何解决Flutter应用程序的兼容性问题
  • 详解Mockito
  • 【论文+App试玩+图像到视频】2311.Animate-anyone:上传1张图片为任何人制作动画(用于角色动画的一致且可控的图像到视频合成)(暂未开源)
  • 【深度学习实验】TensorBoard使用教程【SCALARS、IMAGES、TIME SERIES】
  • 渗透测试(12)- WireShark 网络数据包分析
  • XSS_Labs靶场通关笔记
  • 基于本地缓存制作一个分库分表的分布式ID生成器
  • 美易平台:金融市场的晴雨表与创新服务的融合
  • 文旅项目包括什么?
  • Pointnet++改进优化器系列:全网首发AdamW优化器 |即插即用,实现有效涨点
  • stm32 FOC 电机介绍
  • 【Linux】进程通信——管道
  • 3d gaussian splatting笔记(paper部分翻译)
  • TCP 三次握手以及滑动窗口
  • Vue3 Cli5按需导入ElementPlus
  • playwright自动化项目搭建
  • mysql字符集
  • Elasticsearch:聊天机器人、人工智能和人力资源:电信公司和企业组织的成功组合
  • [AIGC大数据基础] Flink: 大数据流处理的未来