首页 > 范文大全 > 正文

C++中隐式this指针的研究

开篇:润墨网以专业的文秘视角,为您筛选了一篇C++中隐式this指针的研究范文,如需获取更多写作素材,在线客服老师一对一协助。欢迎您的阅读与分享!

摘要: this指针是由系统自动生成的,隐含于每一个类的成员函数中的特殊指针,该指针指向正在对某个成员函数操作的对象。该文通过实例及其汇编代码详细地分析了this指针的特点和它的使用方法,从而进一步的理解c++中的对象和其在内存中的分配情况。

关键词:this指针;对象;成员函数

中图分类号:TP313 文献标识码:A 文章编号:1009-3044(2014)20-4738-02

The Research of Implicit This Pointer in C++

ZHANG Yong-chao

(Dept.of Computer,Jilin institute of Chemical Technology,Jilin 132022,China)

Abstract: this pointer is a special pointer that hidden in every class member function automatically generated by system. It points to the object of operating to a member function.the article analyses characteristics of this pointer and its application method by instances and their assembly code, so as to understanding of objects in C++ and its distribution in memory.

Key words:this pointer;object; member function

1 this指针的引入

类是对一组具有相同或者相似性质对象的抽象描述,类的本质是定义了一种对象类型,它完整的描述了该类型的所有对象的属性和服务。C++语言中,一般把属性称为数据,服务称为函数。从程序设计语言的角度讲,类好比是一种程序员自己定义的数据类型,类可以用来声明对象,一个对象是一个类的实例,类只是逻辑上的抽象,它并不能在物理上存在,只有创建了类的对象之后,在内存中才有一个类的物理表示。当定义了一个类的若干对象后,每个对象都有属于自己的数据成员,但成员函数代码却合用一份。成员函数如何辨别数据成员是哪个对象的呢?例如,我们定义一个三角形类Triangle,再分别定义2个Triangle类的对象t1,t2。假如有t1. area(),应该使用对象t1中的bottom和height,计算出三角形t1的面积,假如有t2. area(),需要利用对象t2中的bottom和height,算出三角形t2的面积,问题是对象t1和t2调用同一个函数area()时,编译系统如何做到分别使用t1或t2对象中的bottom和height计算出各自的面积呢?答案就是在C++的类的成员函数中隐式包含着一个指向当前对象的指针,这个指针被称为this指针。

2 this指针的应用

this指针是指向本类对象的指针,它的值是当前正在调用成员函数的对象的起始地址。例如,在执行t1. area();语句时,编译系统就把第一个三角形对象t1的起始地址传给this指针,这样,在计算面积的成员函数area()引用数据成员时,就会取this指向的对象t1中的数据。area()通过1/2*(bottom*height)计算t1的面积时,其实是执行语句:1/2*(this bottom)*(this height),而此刻this指向的是第一个三角形t1,因此也可以理解为:1/2*(t1. bottom)*(t1.height),所以计算的面积为三角形t1的面积。同样如果有t2. area(),当前对象就换成了t2,编译器就把第二个三角形对象t2的地址赋给this指针,从而计算出t2的面积。可见,this指针是作为隐含的参数被传递给类的成员函数的。程序中成员函数area()的定义为:float Triangle::area(){return 1/2*(bottom*height);}C++把它处理为float Triangle::area (Triangle *this){return 1/2*(this bottom)*(this height);} 在Triangle类的成员函数area()的形参表列中隐含着一个this指针,当this=&t1,area被调用时,编译器先将对象t1的地址传给形参this指针,再根据this当前所指的对象去引用该对象中的数据成员。下面我通过一个简单的例子来对this指针作进一步地分析:

class A

{public:

A(int a,int b)

{ x=a;//等价于thisx=a;

y=b;//等价于thisy=b

cout

~A(){cout

int x,y;};

void main()

{A a1(1,1),a2(2,2),a3(3,3);

cout

cout

cout

程序的运行结果如图1所示:

从上面的实例程序我们可以分析得到:

1) 当一个类产生对象时,首先在内存中给该对象分配空间,并创建this指针指向该对象,然后调用相应的构造函数初始化;this指针的值就是当前对象的地址值,同时等于对象中第一个成员变量的地址值。如程序中:this=&a1=&(a1.x)=0012FF6C。this指向调用成员函数的对象,通常在程序中被省略不写,隐式使用。

2) 对象是根据产生的先后顺序从高地址向低地址分配空间,其中的数据成员是根据定义的顺序从低地址向高地址分配空间,对象所占的内存大小主要指对象的数据成员所占的内存大小,如:sizeof(a1) =sizeof(a1.x)+ sizeof(a1.y)=8。

this指针显式使用:一种情况是当参数与成员变量名相同时,如thisx = x (不能写成x = x,C++中编译不能通过)。 还有一种情况就是在类的非静态成员函数中返回类对象本身的时候,直接使用 return *this;*this表示引用该成员函数的对象。

3 this指针的深入分析

对前面的程序进行反汇编,在VC6.0中,按CTRL+F10,再按ALT+8,可以得到程序的汇编代码:

从上面的汇编代码截图中可以很容易发现,ecx寄存器里就是this指针,this指针通过寄存器ecx传递;通过声明定义的对象的空间分配在栈中。00401829 push ecx将ecx寄存器中的值压栈,也就是把this指针压栈。00401839 pop ecx ecx寄存器出栈,也就是this指针出栈。0040183A mov dword ptr [ebp-4],ecx,将ecx的值放到指定的地方,也就是this指针放到[ebp-4]内。0040183D mov eax,dword ptr [ebp-4],把this指针的值放入eax寄存器内。此刻,this指针指向A的对象,A的对象只有两个int型的成员变量,在A的对象内存中连续存放,也就是说this指针目前指向第一个成员变量x。0040184B mov dword ptr [edx+4],eax给寄存器edx+4指向的地址赋值。this指针加4(sizeof(int))也就是成员变量y的地址,因此这一行就是给第二个成员变量y赋值。

通过以上的分析,可以从底层了解C++中this指针的实现方法。虽然不同的编译器会使用不同的处理方法,但是基本原理差不多。

4 this指针的小结

this 是系统自动生成的,隐含于每一个类的成员函数中的特殊指针,该指针指向正在对某个成员函数操作的对象。当某个对象调用成员函数时,编译器首先把该对象的地址赋给指针this,该成员函数的this指针便指向这个对象。一般不必显式的使用this指针来引用数据成员,当参数与成员变量名相同或者需要把对象本身作为参数传递给另一个函数的时候才需要显式的使用。this指针是局部数据,静态成员函数不存在this指针。

参考文献:

[1] 吕凤翥.C++语言基础教程[M].2版.北京:清华大学出版社,2007.

[2] 李隆庚.利用this指针深入理解C++程序[J].唐山学院学报,2007,20(4).

[3] Stanley B.Lippman.C++Primer[M]. 4版.北京:人民邮电出版社,2008.