首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

到底什么是this指针?解决思路

2012-04-04 
到底什么是this指针?当时我初学C++的时候,觉得this简直是一个怪物,书本上说this指针不存在于对象之中,因此

到底什么是this指针?
当时我初学C++的时候,觉得this简直是一个怪物,书本上说
this指针不存在于对象之中,因此sizeof(X)时不体现this的大小
但,根据我当时头脑中的一些概念,变量先定义后使用,凡是变量都可取地址
this指针就有了一些很“怪”的特征:没有定义,不许取地址,不能赋值,而且能够指向对象

不知道其他人是不是有相似的感觉,总之,我觉得this很神奇,于是也萌发一个一探究竟的欲望
也请教过一些人,无不是被K的灰头土脸,基本所有人都说这是一个无意义的问题,为什么无意义
我想,可能是即使你不了解它背后的一些东西,对使用来说,一点问题也没有,由此我倒是想到了
孔已己写回字,被一个伙计都看不起,我基本都快成孔已己了,其实我想,多会写几个回字倒也没
什么大了不起也不值得被人猛K,但是,不能只会写回字,对不对,除了写回字以外一无所长,
这就大大的糟糕了,做技术的也是一样,不能只钻牛角尖,但是偶尔钻一钻牛角尖我想也无伤大雅

好,说完我为什么要知道this指针到底是什么之后就进入正题


bj在它的著作(C++语言的设计与演化   p62)里说在早期的C++里
this是一个可以被赋值的东东,只是在继承在堆栈里很难处理,后来才被淘汰掉
class   X{
//...
public:
      X();
//...
};

X::X(){
        this=my_alloc(sizeof(X));
        //...
}

X   x;//为x分配内存

既然可以为它赋值那么就意味着this可能是真实存在的这么一个变量

之后我又机会读到了深度探索C++对象模型,书中对this的描述是,this是一个函数参数
 
float   manitude3d(const   Point3d   *_this){...};
float   Point3d::manitude3d()const{...}
这两种方式是等价的,编译器在内部将后者转化为前者,因此
obj.magintude();变成了maginitude_7Point3dFv(&obj);

看完相关的章节,觉得自己对于C++是有了一定的理解,知道this为什么只能
在成员函数中使用,它是一个函数参数,函数参数能在定义它的函数外使用吗?当然不能

也许到这里理解的可能就够了,但是偏偏我这个人有点拧,我就想既然this是真实的变量,那我为什么不能
取它地址?给它赋值?又过了一段时间,我开始学习汇编,用的是清华的《汇编语言》作者王爽,这真的是
一本不错的书,通俗易懂,拿来入门真是合适不过了,以前我用的是冶金工业出版社的《80X86汇编语言程序设计》
讲的我就是晕的一塌糊涂,由此我也想到了,一本好书的定义,应该是能让人一看就茅舍顿开,而一本垃圾书则相反
通过一段时间的学习后(这段时间我待业,刚好有足够的时间)我分别跟踪了VC6.0和BCB6.0中的成员函数执行过程
终于觉得是很久以来想不通的东西都明白了,很爽

先说VC6.0
当程序执行
x.foo();
lea   ecx,dword   ptr[ebp-4]                 //对象地址存储到ecx中
call   @ILT   +10(X::foo)(0040100f)   //跳转到0040100f处
0040100f   jmp   X::foo                           //0040100f处的jmp跳转的函数真正的地址

void   X::foo(){
//...
mov   doword   ptr[ebp-4],ecx
//将对象地址从ecx中读出,写入到foo的ebp-4处
//...
}

由此可见,在VC中对象地址是通过寄存器变量传递进成员函数,但是进入函数后做完一些初始化的工作以后
把对象地址写入到foo的ebp-4处,这个ebp-4不是调用前的ebp-4,这里存在着压栈等多种操作,很难一下说清楚
由此,了解了VC成员函数的调用过程,我们可以大胆做一些测试程序

void   X::foo(X   *p){
        __asm{
            mov   eax,doword   ptr[ebp+8]
            mov   dword   ptr[ebp-4],eax
            //this   =   p
      }
      this-> a=10;//p-> a=10;
}//偷梁换柱,this实际已经指向*p

void   X::foo(){
        X   **p;
        __asm{
            lea   eax,dword   ptr[ebp-4]
            mov   dword   ptr   [ebp-8],eax
            //p=&this
      }
      (*p)-> a=10;//this-> a=10;      
}//p指向了this因此**p==*this

再说bcb6.0,当程序执行
x.foo();
lea   eax,[ebp-0x04]
push   eax                     //将对象地址压栈
call   X::foo()           //调用X::foo()

[解决办法]
顶一下.
[解决办法]
因为this是一个保留字,告诉c++编译器,变量或者函数时使用属于该类的变量或方法
------解决方案--------------------


总之是本对象用来绑定类中成员函数用的,要知道,你是不可能取到成员函数的地址的,这和普通函数不一样。
[解决办法]
哦,原来是这样啊
[解决办法]
支持一下!
[解决办法]
楼主的代码不能运行成功啊,总报非法内存访问的错误(vc6.0)

再用bcb6.0试试,报链接错误:[Linker Error] Unresolved external '__InitVCL ' referenced from D:\PROGRAM FILES\BORLAND\CBUILDER6\LIB\CP32MTI.LIB|crtlvcl
[Linker Error] Unresolved external '__ExitVCL ' referenced from D:\PROGRAM FILES\BORLAND\CBUILDER6\LIB\CP32MTI.LIB|crtlvcl

这是怎么回事?
[解决办法]
普通的成员函数一般都隐含了一个this指针,this指针指向类的对象本身,因为普通成员函数总是具体的属于某个类的具体对象的。通常情况下,this 是缺省的。如函数fn()实际上是this-> fn()。但是与普通函数相比,静态成员函数由于不是与任何的对象相联系,因此它不具有this指 针。从这个意义上讲,它无法访问属于类对象的非静态数据成员,也无法访问非静态成员函数,它只能调用其余的静态成员函数。
http://blog.csdn.net/kiss0kill/archive/2006/12/15/1444211.aspx
[解决办法]
就好比有个单人厕所(非静态成员函数)是某个寝室(类) 的
某个人正在使用厕所(this 指向这个人)
不知道理解怎样
[解决办法]
purely conceptual...
[解决办法]
ugg 有个帖子 《关于this指针的深入探讨》
很不错的 不过时间很老了 2006-1-24 9:59:12 的,我这里有收藏,要的话给个MAIL

[解决办法]
受益匪浅

热点排行
Bad Request.