文章目录
一、this指针的引出
- 我们先来定义一个日期类
Date
,下面这段代码执行的结果是什么呢?
classDate{public:voidInit(int year,int month,int day){
_year = year;
_month = month;
_day = day;}voidprint(){
cout << _year <<"-"<< _month <<"-"<< _day << endl;}private:int _year;int _month;int _day;};intmain(){
Date d1, d2;
d1.Init(2022,5,11);
d2.Init(2022,5,12);
d1.print();
d2.print();return0;}
- 可以看到分别打印出了两个日期,它是怎么知道改打印哪个的?
- 我们来分析一下,先看一下汇编代码,看一看
- 我们看到上面的代码是调用的同一个函数,那么编译器是如何知道那两个日期的?
- 其实C++里有一个隐形的this指针,在微软的官方文档也有说明
- 在使用函数的时候其实里面传了一个地址,然后有一个隐的this指针来接收
原形是这样:
- 那为什么这里报错了呢?
- 因为不必要写,这个是隐含的~~,我们可以直接在类里面使用
二、this指针的特性
- 刚刚上面也给你看了原形,细心的烙铁已经发现了,这个this指针是有一个const修饰的,而且这个const是在
*
的右边
- 这里的const修饰,我在C语言的指针部分已经讲过了—>指针章节
- 下面我们回忆一下~
- 到这里就得出的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、正常运行
classA{public:voidPrint(){
cout <<"Print()"<< endl;}private:int _a;};intmain(){
A* p =nullptr;
p->Print();return0;}
- 已经完美运行了,因为我这里没有访问类里的对象,所以可以正常运行
第二道:下面程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行
classA{public:voidPrintA(){
cout << _a << endl;}private:int _a;};intmain(){
A* p =nullptr;
p->PrintA();return0;}
- 这里引发了空指针,因为我需要打印这里的
_a
,就要找到那块空间
- 也就可以写成这样,this指针是空指针,解引用就会报错
- 所以this指针是可以为空的,只要在成员函数内部不访问其内容,程序可以正常执行的。
最后本篇文章介绍了C++中隐含的this指针,特性,看完希望你学有所成!!!
版权归原作者 仍在探索未知中 所有, 如有侵权,请联系我们删除。