祥解this指针.doc
上传人:sy****28 上传时间:2024-09-14 格式:DOC 页数:5 大小:28KB 金币:16 举报 版权申诉
预览加载中,请您耐心等待几秒...

祥解this指针.doc

祥解this指针.doc

预览

在线预览结束,喜欢就下载吧,查找使用更方便

16 金币

下载此文档

如果您无法下载资料,请参考说明:

1、部分资料下载需要金币,请确保您的账户上有足够的金币

2、已购买过的文档,再次下载不重复扣费

3、资料包下载后请先用软件解压,在使用对应软件打开

HYPERLINK"http://it.china-b.com/cxsj/cc/20090525/25448_1.html"\l"#"祥解C++中的this指针有下面的一个简单的类:classCNullPointCall;intCNullPointCall::m_iStatic=0;voidCNullPointCall::Test1voidCNullPointCall::Test2voidCNullPointCall::Test3voidCNullPointCall::Test4那么下面的代码都正确吗?都会输出什么?CNullPointCallpNull=NULL;//没错,就是给指针赋值为空pNull-Test1;//call1pNull-Test2;//call2pNull-Test3;//call3pNull-Test4;//call4你肯定会很希奇我为什么这么问。一个值为NULL的指针怎么可以用来调用类的成员函数呢?!可是实事却很让人吃惊:除了call4那行代码以外,其余3个类成员函数的调用都是成功的,都能正确的输出结果,而且包含这3行代码的程序能非常好的运行。经过细心的比较就可以发现,call4那行代码跟其他3行代码的本质区别:类CNullPointCall的成员函数中用到了this指针。对于类成员函数而言,并不是一个对象对应一个单独的成员函数体,而是此类的所有对象共用这个成员函数体。当程序被编译之后,此成员函数地址即已确定。而成员函数之所以能把属于此类的各个对象的数据区别开,就是靠这个this指针。函数体内所有对类数据成员的访问,都会被转化为this-数据成员的方式。而一个对象的this指针并不是对象本身的一部分,不会影响sizeof(“对象”)的结果。this作用域是在类内部,当在类的非静态成员函数中访问类的非静态成员的时候,编译器会自动将对象本身的地址作为一个隐含参数传递给函数。也就是说,即使你没有写上this指针,编译器在编译的时候也是加上this的,它作为非静态成员函数的隐含形参,对各成员的访问均通过this进行。对于上面的例子来说,this的值也就是pNull的值。也就是说this的值为NULL.而Test1()是静态函数,编译器不会给它传递this指针,所以call1那行代码可以正确调用(这里相当于CNullPointCall::Test1());对于Test2()和Test3()两个成员函数,虽然编译器会给这两个函数传递this指针,但是它们并没有通过this指针来访问类的成员变量,因此call2和call3两行代码可以正确调用;而对于成员函数Test4()要访问类的成员变量,因此要使用this指针,这个时候发现this指针的值为NULL,就会造成程序的崩溃。其实,我们可以想象编译器把Test4()转换成如下的形式:voidCNullPointCall::Test4而把call4那行代码转换成了下面的形式:CNullPointCall::Test4;所以会在通过this指针访问m_iTest的时候造成程序的崩溃。下面通过查看上面代码用VC2005编译后的汇编代码来具体解释一下神奇的this指针。上面的C++代码编译生成的汇编代码是下面的形式:CNullPointCallpNull=NULL;0041171Emovdwordptr[pNull],0pNull-Test1;00411725callCNullPointCall::Test1pNull-Test2;0041172Amovecx,dwordptr[pNull]0041172DcallCNullPointCall::Test2pNull-Test3;00411732push0Dh00411734movecx,dwordptr[pNull]00411737callCNullPointCall::Test3pNull-Test4;0041173Cmovecx,dwordptr[pNull]0041173FcallCNullPointCall::Test4通过比较静态函数Test1()和其他3个非静态函数调用所生成的的汇编代码可以看出:非静态函数调用之前都会把指向对象的指针pNull(也就是this指针)放到ecx寄存器中(movecx,dwordptr[pNull])。这就是this指针的非凡之处。看call3那行C++代码的汇编代码就可以看到this指针跟一般的函数参数的区别:一般的函数参数是直接压入栈中(push0Dh),而this指针却被放到了ecx寄存器中。在类的非成员函数中假如要用到类的成员变量,就可以通过访问ecx寄存器来得到指向对象的this指针,然后再通过this指针加上成员变量的偏移量来找