一文详解C++中隐含的this指针

 更新时间:2024年01月29日 10:07:48   作者:仍在探索未知中  
这篇文章主要带大家详细了解一下C++中隐含的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修饰

在这里插入图片描述

  • 到这里就得出的this本身是不被修改的,但是做指向的值是可以被修改
  • 我们可以在类中打印一下this指针的地址,再打印一下d1和d2的地址,我们来看一下:

在这里插入图片描述

  • 得到结果就是this指针指向一个指向当前对象的指针
  • 我们还可以下面这样,是不会报错的,但是不能向上面直接在形参就写上

在这里插入图片描述

特点:

1、形参和实参的位置,我们不能显示写

2、函数内部可以使用

最后总结一下:

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

【面试题】

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]

在这里插入图片描述

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指针的详细内容,更多关于C++ this指针的资料请关注脚本之家其它相关文章!

相关文章

  • C语言实现快速排序改进版

    C语言实现快速排序改进版

    这篇文章主要为大家详细介绍了C语言实现快速排序的改进代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-08-08
  • C语言字符串转换为Python字符串的方法

    C语言字符串转换为Python字符串的方法

    这篇文章主要介绍了C语言字符串转换为Python字符串的方法,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-07-07
  • C++ 十进制转换为二进制的实例代码

    C++ 十进制转换为二进制的实例代码

    这篇文章介绍了C++ 十进制转换为二进制的实例代码,有需要的朋友可以参考一下
    2013-10-10
  • Qt QFrame的具体使用

    Qt QFrame的具体使用

    本文主要介绍了Qt QFrame的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • C语言编程深入理解取整取余取模问题示例分析

    C语言编程深入理解取整取余取模问题示例分析

    这篇文章主要为大家介绍了C语言编程深入理解取整取余取模问题的示例分析详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2021-11-11
  • Windows配置VSCode+CMake+Ninja+Boost.Test的C++开发环境(教程详解)

    Windows配置VSCode+CMake+Ninja+Boost.Test的C++开发环境(教程详解)

    这篇文章主要介绍了Windows配置VSCode+CMake+Ninja+Boost.Test的C++开发环境,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-05-05
  • C++插件化 NDD源码的插件机制实现解析

    C++插件化 NDD源码的插件机制实现解析

    这篇文章主要介绍了C++插件化 NDD源码的插件机制实现解析,这里再介绍推荐下优秀的国产软件开源项目 NDD(notepad--),一个支持windows/linux/mac的文本编辑器,目标是要国产替换同类软件,需要的朋友可以参考下
    2023-03-03
  • C++多线程编程时的数据保护

    C++多线程编程时的数据保护

    这篇文章主要介绍了C++多线程编程时的数据保护,作者针对C++11版本中的新特性做出了一些解说,需要的朋友可以参考下
    2015-07-07
  • 关于C++中sort()函数的用法,你搞明白了没

    关于C++中sort()函数的用法,你搞明白了没

    这篇文章主要介绍了关于C++中sort()函数的用法,并通过三种方法介绍了按降序排列的实现代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03
  • C语言通过案例讲解并发编程模型

    C语言通过案例讲解并发编程模型

    所谓并发编程是指在一台处理器上“同时”处理多个任务。并发是在同一实体上的多个事件。多个事件在同一时间间隔发生,下面我们根据样例来理解
    2022-04-04

最新评论