【C++】自引用this指针的秘密

【C++】自引用this指针的秘密关于this指针的一个经典回答当我们在进入一个房子之后,可以看见房子里的桌子、椅子、地板等,但是看不到房子的全貌。对于一个类的实例来说,你可以看到它的成员函数、成员变量,但是实例本身呢?this是一个指针,它时时刻刻指向这个个实例。识别一个类可以分为哪三步?①识别类名。②识别数据成员。③识别成员函数并修改之。this指针的特性:①this指针的类型:类类型*const。②thi…

大家好,又见面了,我是你们的朋友全栈君。

关于this指针的一个经典回答

当我们在进入一个房子之后,可以看见房子里的桌子、椅子、地板等,但是看不到房子的全貌。对于一个类的实例来说,你可以看到它的成员函数、成员变量,但是实例本身呢?this是一个指针,它时时刻刻指向这个个实例。

识别一个类可以分为哪三步?

①识别类名。
②识别数据成员。
③识别成员函数并修改之。

this指针的特性:

①this指针的类型:类类型 * const。
②this指针并不是对象本身的一部分,不影响sizeof的结果。
③this的作用域在类成员函数的内部(不严谨)。
④this指针是类成员函数的第一个默认隐含参数,编译器自动维护传递,类编写者不能显示传递。
⑤只有在类的非静态成员函数中才可以使用this指针,其他任何函数都不可以。

  • this指针的功能及原理(通过一个例子来说明)

#include <iostream>
#include <Windows.h>
using namespace std;
class A
{ 
   
public:
	A(int x1)
	{ 
   
		x = x1;
	}
	void disp()
	{ 
   
		cout<<"this="<<this<<" when x="<<this->x<<endl;
	}
private:
	int x;
};
int main()
{ 
   
	A a(1),b(2),c(3);
	a.disp();
	b.disp();
	c.disp();
	system("pause");
	return 0;
}

在这里插入图片描述

从测试结果可以看出:对于类定义的不同对象,其地址对应相应的值,即this指针的值是当前调用成员函数的对象的起始地址。当调用成员函数a.disp()时,编译系统就会把对象a的起始地址赋值给this指针,于是在成员函数引用数据成员时,就可以通过this指针索引到对象a的数据成员。

  • _thiscall调用约定

①_thiscall只能够用在类的成员函数上。
②参数从右向左压栈。
③如果参数个数确定,this指针通过ecx传递给被调用者,如果参数不确定,this指针在所有参数被压栈后压入堆栈。
④对参数个数不定的,调用者清理堆栈,否则函数自己清理堆栈。

为什么叫this指针,而不是引用呢?

首先应该明确的是指针和引用在底层的实现是相同的,之所以叫this指针,是因为最开始将C++称作带类的C,而引用则是在C++1.0版才加入使用的,因此叫做this指针。
this指针有没有可能指向NULL呢?

有可能,可以定义一个类对象的指针并使其初始化为NULL,具体实现见代码及测试图。

#include <iostream>
#include <Windows.h>
using namespace std;
class CTest
{ 
   
public:
	void FunTest()
	{ 
   
		cout<<"this:"<<this<<endl;
	}
};
void FunTest()
{ 
   
	CTest* pt = NULL;
	pt->FunTest();
}
int main()
{ 
   
	FunTest();
	system("pause");
	return 0;
}

在这里插入图片描述

关于this指★针易混淆的问题

  • this指针是什么时候创建的?

this在成员函数的开始执行前构造的,在成员的执行结束后清除

  • this指针存放于何处?堆、栈、全局变量还是其他地方?

this指针会因编译器不同,而放置的位置不同。可能是栈,也可能是寄存器,甚至全局变量。

  • this指针是如何访问类中的变量的?

如果不是类,而是结构的话,那么,如何通过结构指针来访问结构中的变量呢?如果你明白这一点的话,那就很好理解这个问题了。在C++中,类和结构是只有一个区别的:类的成员默认是private,而结构是public。this是类的指针,如果换成结构,那this就是结构的指针了。

  • 我们只有获得一个对象后,才能通过对象使用this指针,如果我们知道一个对象this指针的位置,能否直接使用?

this指针只有在成员函数中才有定义。因此,你获得一个对象后,也不能通过对象使用this指针。所以,我们也无法知道一个对象的this指针的位置(只有在成员函数里才有this指针的位置)。当然,在成员函数里,你是可以知道this指针的位置的(可以&this获得),也可以直接使用的。

  • 每个类编译后,是否创建一个类中函数表来保存函数指针,以便来调用函数?

普通的类函数(不论是成员函数,还是静态函数),都不会创建一个函数表来保存函数指针的。只有虚函数才会被放到函数表中。但是,既使是虚函数,如果编译器能明确知道调用的是哪个函数,编译器就不会通过函数表中的指针来间接调用,而是会直接调用该函数。

  • this指针如何传递给类中函数的?绑定?还是在函数参数的首参数就是this指针?

大多数编译器通过ecx寄存器传递this指针。事实上,这也是一个潜规则。一般来说,不同编译器都会遵从一致的传参规则,否则不同编译器产生的obj就无法匹配了。在call之前,编译器会把对应的对象地址放到eax中。this是通过函数参数的首参来传递的。this指针在调用之前生成,至于“类实例后函数”,没有这个说法。类在实例化时,只分配类中的变量空间,并没有为函数分配空间。自从类的函数定义完成后,它就在那儿,不会跑的。

  • 为什么this指针不能再静态函数中使用?

静态成员函数并不是针对某个类的实例对象,而是属于整个类的,为所有的对象实例所共有。它在作用域的范围内是全局的,独立于类的对象之外的。它只对类内部的静态成员变量做操作。当实例化一个类的对象时候,里面不存在静态成员的。this指针是相当于一个类的实例的指针,this是用来操作对象实例的内容的,既然静态成员函数和变量都是独立于类的实例对象之外的,它就不能用this指针,也不能操作非静态成员。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/145691.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Laravel 框架集成 UEditor 编辑器的方法

    Laravel 框架集成 UEditor 编辑器的方法

  • 开发一款Android App,从零开始详细讲解[通俗易懂]

    开发一款Android App,从零开始详细讲解[通俗易懂]入门篇:第一篇:开发环境篇第二篇:材料设计篇第三篇:规范开发篇第四篇:从项目开发到上架篇(篇章调整,最后更新)进阶篇:第五篇:设计模式篇第六篇:网络请求篇(上)    网络请求篇(下)第七篇:图片处理篇第八篇:数据库篇第九篇:开源资源篇高阶篇:第十篇:自定义控件篇第十一篇:跨进程篇关于Demo写这个系列的文章的同时,也在做一个小Demo。功能很简单,利用豆瓣电影Api实现一款基于Android的电影集合的App。starmeonGitHub! 该项目的数据源来自于豆瓣;

  • java暗装没有快捷键,java强行videos

    java暗装没有快捷键,java强行videosjava强行videos“一会儿就回来了,强行关了又开更费电。”“但我很喜欢做。”然后她就更用力地抱紧他,小脸也贴到了他背后。小萌一号:强行“那你要照顾好自己和梨香哦,我会看好家的,早点回来吖!”“现在呢?”“……”燥热。听到沈郁要出门,强行白小萌也想跟着去的,但它只是一只懒惰的猫咪,现在舒服的很,爬起身来看了看,又扭头躺下做按摩了。反正沈郁每天晚上都和小萌睡,强行白天就让给梨香吧,白小萌觉得自己…

  • 希尔排序算法实例讲解_十大算法排名

    希尔排序算法实例讲解_十大算法排名一、什么是希尔排序1.概念希尔排序(ShellSort)是把记录按下标的一定增量分组,对每组使用插入排序算法,随着增量逐渐减少,每组包含的元素越来越多,当增量减至1时,所有元素被分为一组,算法终止2.算法原理这是一个无序数列:1、5、8、4、7、2、6、3,我们要将它按从小到大排序。按照希尔排序的思想,我们先把数列进行分组排序首先,我们选择序列长度的一半4,作为增量进行分组如果所示,1和7一组,5和2一组,8和6一组,4和3一组,共四组然后,我们对每一组进行插入排序,排序后序列如下经

    2022年10月27日
  • 软件著作权申请流程_如何申请软件著作权

    软件著作权申请流程_如何申请软件著作权现在越来越多的安卓市场需要软著才能注册或者是才能上线,申请软著势在必行。最简单的方式,简单的准备资料,找第三方代理,不过这样可能花费数百毛爷爷,如果是急需加急,可能是几千。现在简单说一下自己申请的流程:首先贴出中国版权保护中心网站中国版权保护中心:http://apply.ccopyright.com.cn/cpcc/column_list_bqdj.jsp请使用IE浏览器打开一.注册

  • カード名義_acwing题库

    カード名義_acwing题库原题链接给定一棵包含 n 个节点的有根无向树,节点编号互不相同,但不一定是 1∼n。有 m 个询问,每个询问给出了一对节点的编号 x 和 y,询问 x 与 y 的祖孙关系。输入格式输入第一行包括一个整数 表示节点个数;接下来 n 行每行一对整数 a 和 b,表示 a 和 b 之间有一条无向边。如果 b 是 −1,那么 a 就是树的根;第 n+2 行是一个整数 m 表示询问个数;接下来 m 行,每行两个不同的正整数 x 和 y,表示一个询问。输出格式对于每一个询问,若 x 是 y 的祖先则输

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号