this指针(一个永远指向调用对象首地址的指针)
为什么要使用this指针
在c++刚开始学习的过程中,通篇都在强调“类是对象的抽象,对象是类的示例”。那么当同一个类内的不同对象调用同一个函数体的时候,函数体将不同对象的数据进行整合计算,得到的值在返回到该对象的过程是如何实现的呢?
在c语言中我们习惯使用一个指向结构体的指针实现,而在c++中,函数体会隐式的调用this指针,将对象的首地址传给函数体而实现的。
this指针的特性
- this指针的类型是类类型 (*const)。
- this指针只能指向对象的首地址。
- this指针并不属于该类,不影响sizeof()的结果。
- this指针是非静态成员函数的一个隐含指针形参,属于编译器调用,不需要手动添加,当然显式的将this指针直接在成员函数内写出也是可以的
成员函数被调用时fun(int a) 的原型在编译器看来就是 fun(*const this,int a)
this指针不可被修改,成员函数参数列表第一个默认为const this
- this指针的作用域是非静态成员函数内,其他任何函数都无法调用this指针。
this指针的传参方式
-参数个数确定,this指针通过ecx传递给非静态成员函数
调用函数约定_cdecl _cdecl:参数从右向左传递,参数个数固定,由函数本身清理堆栈。
-参数个数不定,例如(fun(…)),this指针在所有参数被压入堆栈之后再入堆栈 。
调用函数约定 _thiscall _thiscall:c参数从右向左传递,参数个数不定,由调用者清理堆栈。
this指针的实际使用
#include<stdio.h>
struct DATA
{
int year;
int month;
int day;
};
void is_leapyear(struct DATA *P)
{
if((p.year%400!=0&&p.year%4==0)||(p.year%400==0))
{
printf("%d is a leapyear\n",p.year);
}
else
printf("is not a leapyear\n",p.year);
}
int main()
{
struct DATA a={2002,2,28};
struct DATA b={2010,4,10};
is_leapyear(a);
is_leapyear(b);
return 0;
}
这是c在使用结构体时,通过调用*p(一个指向结构体的指针)进行调用,实现同一个结构体的不同对象在调用同一个函数的时候实现不同操作。
那么在c++中是如何实现的呢?
class Date{
int year;
int month;
int date;
public Date(int year,int month,int day
{
this.month =month; //*显式调用this指针*
this.year =year;
this.day =day;
}
public void setdate(int year,int month,int day){
this.day =day;
this.month =month;
this.year =year;
}
public bool Leapyear()
{
if((year%4==0)&&(year%100!=0)||(year%400==0))
printf("is leapyear");
else
printf("is not leapyear");
}
int main()
{
cout << ( Date( y, m, d ).isLeap() ? "是闰年" : "不是闰年" );
b.data={2002.2.28};
b.data.isleapyear();
return 0;
}
有关this指针比较容易混淆的问题
1.this指针是什么时候创建的?
this在成员函数开始执行前构造,在成员的执行结束后清楚,但是如果class或者struct里面没有方法的话,它们是没有构造函数的,只能当做C的struct使用。采用 TYPE xx的方式定义的话,在栈里分配内存,这时候this指针的值就是这块内存的地址。采用new的方式 创建对象的话,在堆里分配内存,new操作符通过eax返回分配 的地址,然后设置给指针变量。之后去调 用构造函数(如果有构造函数的话),这时将这个内存块的地址传给ecx,之后构造函数里面怎么处理请 看上面的回答。
2.this指针存放在何处?堆、栈、全局变量、还是其他?
this指针会因编译器不同而有不同的放置位置。可能是栈,也可能是寄存器,甚至全局变量。在汇编级 别里面,一个值只会以3种形式出现:立即数、寄存器值和内存变量值。不是存放在寄存器就是存放在内 存中,它们并不是和高级语言变量对应的。
3我们只有获得一个对象后,才能通过对象使用this指针。如果我们知道一个对象的this指针的位置,可以直接使用吗?
this指针只有在成员函数中才有定义。因此,你获得一个对象后,也不能通过对象使用this指针。所以,我们无法知道一个对象的this指针的位置(只有在成员函数里才有this指针的位置)。当然,在成员函数里,你是可以知道this指针的位置的(可以通过&this获得),也可以直接使用它。