摘自:http://blog.chinaunix.net/uid-21411227-id-1826942.htmlhtml
1. this指针的用处:ios
一个对象的this指针并非对象自己的一部分,不会影响sizeof(对象)的结果。this做用域是在类内部,当在类的非静态成员函数中访问类的非静态成员的时候,编译器会自动将对象自己的地址做为一个隐含参数传递给函数。也就是说,即便你没有写上this指针,编译器在编译的时候也是加上this的,它做为非静态成员函数的隐含形参,对各成员的访问均经过this进行。 例如,调用date.SetMonth(9) <===> SetMonth(&date, 9),this帮助完成了这一转换 .函数
2. this指针的使用:优化
一种状况就是,在类的非静态成员函数中返回类对象自己的时候,直接使用 return *this;另一种状况是当参数与成员变量名相同时,如this->n = n (不能写成n = n)。ui
3. this指针程序示例:this
this指针存在于类的成员函数中,指向被调用函数所在的类实例的地址。 根据如下程序来讲明this指针 spa
#include<iostream.h> .net
class Point { int x, y; unix
public: 指针
Point(int a, int b) { x=a; y=b;}
void MovePoint( int a, int b){ x+=a; y+=b;}
void print(){ cout<<"x="<<x<<"y="<<y<<endl;}
};
void main( ) {
Point point1( 10,10);
point1.MovePoint(2,2);
point1.print( );
}
当对象point1调用MovePoint(2,2)函数时,即将point1对象的地址传递给了this指针。
MovePoint函数的原型应该是 void MovePoint( Point *this, int a, int b);第一个参数是指向该类对象的一个指针,咱们在定义成员函数时没看见是由于这个参数在类中是隐含的。这样point1的地址传递给了this,因此在MovePoint函数中便显式的写成:
void MovePoint(int a, int b) { this->x +=a; this-> y+= b;} 便可以知道,point1调用该函数后,也就是point1的数据成员被调用并更新了值。 即该函数过程可写成 point1.x+= a; point1. y + = b;
4. 关于this指针的一个经典回答:
当你进入一个房子后,
你能够看见桌子、椅子、地板等,
可是房子你是看不到全貌了。
对于一个类的实例来讲,
你能够看到它的成员函数、成员变量,
可是实例自己呢?
this是一个指针,它时时刻刻指向你这个实例自己
5. 类的this指针有如下特色:
(1)this只能在成员函数中使用。
全局函数、静态函数都不能使用this.
实际上,成员函数默认第一个参数为T * const this。
如:
class A
{
public:
int func(int p)
{
}
};
其中,func的原型在编译器看来应该是:
int func(A * const this,int p);
(2)因而可知,this在成员函数的开始前构造,在成员函数的结束后清除。
这个生命周期同任何一个函数的参数是同样的,没有任何区别。
当调用一个类的成员函数时,编译器将类的指针做为函数的this参数传递进去。如:
A a;
a.func(10);
此处,编译器将会编译成:
A::func(&a,10);
看起来和静态函数没差异,对吗?不过,区别仍是有的。编译器一般会对this指针作一些优化,所以,this指针的传递效率比较高--如VC一般是经过ecx寄存器传递this参数的。
(3)几个this指针的易混问题。
A. this指针是何时建立的?
this在成员函数的开始执行前构造,在成员的执行结束后清除。
可是若是class或者struct里面没有方法的话,它们是没有构造函数的,只能当作C的struct使用。采用 TYPE xx的方式定义的话,在栈里分配内存,这时候this指针的值就是这块内存的地址。采用new的方式 建立对象的话,在堆里分配内存,new操做符经过eax返回分配 的地址,而后设置给指针变量。以后去调 用构造函数(若是有构造函数的话),这时将这个内存块的地址传给ecx,以后构造函数里面怎么处理请 看上面的回答。
B. this指针存放在何处?堆、栈、全局变量,仍是其余?
this指针会因编译器不一样而有不一样的放置位置。多是栈,也多是寄存器,甚至全局变量。在汇编级 别里面,一个值只会以3种形式出现:当即数、寄存器值和内存变量值。不是存放在寄存器就是存放在内 存中,它们并非和高级语言变量对应的。
C. this指针是如何传递类中的函数的?绑定?仍是在函数参数的首参数就是this指针?那么,this指针 又是如何找到“类实例后函数的”?
大多数编译器经过ecx寄存器传递this指针。事实上,这也是一个潜规则。通常来讲,不一样编译器都会听从一致的传参规则,不然不一样编译器产生的obj就没法匹配了。
在call以前,编译器会把对应的对象地址放到eax中。this是经过函数参数的首参来传递的。this指针在调用以前生成,至于“类实例后函数”,没有这个说法。类在实例化时,只分配类中的变量空间,并无为函数分配空间。自从类的函数定义完成后,它就在那儿,不会跑的。
D. this指针是如何访问类中的变量的?
若是不是类,而是结构体的话,那么,如何经过结构指针来访问结构中的变量呢?若是你明白这一点的话,就很容易理解这个问题了。
在C++中 ,类和结构是只有一个区别的:类的成员默认是private,而结构是public。
this是类的指针,若是换成结构,那this就是结构的指针了。
E. 咱们只有得到一个对象后,才能经过对象使用this指针。若是咱们知道一个对象this指针的位置,能够直接使用吗?
this指针只有在成员函数中才有定义。所以,你得到一个对象后,也不能经过对象使用this指针。因此,咱们没法知道一个对象的this指针的位置(只有在成员函数里才有this指针的位置)。固然,在成员函数里,你是能够知道this指针的位置的(能够经过&this得到),也能够直接使用它。
F. 每一个类编译后,是否建立一个类中函数表保存函数指针,以便用来调用函数?
普通的类函数(不管是成员函数,仍是静态函数)都不会建立一个函数表来保存函数指针。只有虚函数才会被放到函数表中。可是,即便是虚函数,若是编译器能明确知道调用的是哪一个函数,编译器就不会经过函数表中的指针来间接调用,而是会直接调用该函数。