this指针探秘

icoding 2007-02-05 11:04:51
当时我初学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()
...全文
2399 57 打赏 收藏 转发到动态 举报
写回复
用AI写文章
57 条回复
切换为时间正序
请发表友善的回复…
发表回复
ankey888 2011-08-12
  • 打赏
  • 举报
回复
特地搜索出来看看this的,还是不怎么懂!
heylnsld 2010-12-25
  • 打赏
  • 举报
回复
刚接触this指针,头都大了
traso 2008-06-28
  • 打赏
  • 举报
回复
mark
偶看看.
xiaoc10 2008-06-28
  • 打赏
  • 举报
回复
mark
jinwei1984 2008-06-28
  • 打赏
  • 举报
回复
mark study
vlient 2008-06-27
  • 打赏
  • 举报
回复
this指针其实就是指向当前对象的的一个指针,就跟下面的p 地址一样。
ClassA *p = new ClassA()
在调用这个对象的成员函数的时候,this指针会作为隐含参数通过ECX传递。

这东东搞得太玄乎反而会让人迷惑
icoding 2008-06-27
  • 打赏
  • 举报
回复
楼上,我不知道你想说啥,回家检讨先吧

this指针是变量,这个是事实,不过不一定是内存变量,也可能是寄存器变量,具体看编译器怎么决定,语言没有规定,所谓优化为内存变量...实在不知道你说什么...

亦即,调用动态创建的对象的函数时,编译器是如何
获得这个对象的地址,并且把它传到类的函数去?
--------------------
嘿嘿,你是想骗我多告诉你一些东西吧?就不告诉你,从你的提问就可以知道你其实是概念不清,好了,就说这么多
lingol 2008-06-27
  • 打赏
  • 举报
回复
我来提一个真正有意思的问题吧:
动态创建的对象的this指针是如何获得的?亦即,调用动态创建的对象的函数时,编译器是如何
获得这个对象的地址,并且把它传到类的函数去?
lingol 2008-06-27
  • 打赏
  • 举报
回复
坚持说this指针是内存变量的人(如13楼),试试取this的地址看看
lingol 2008-06-27
  • 打赏
  • 举报
回复
说了半天,其实this指针只是一个概念上的东西,编译器完全可以把它优化成对象的内存地址。
所以那些说可以对this指针赋值的人,注意一下是否在所有编译器上都可以,是否所有编译模式都可以。
矛盾博弈 2008-06-24
  • 打赏
  • 举报
回复
C++ Primer 4 中有些关于这个的阐述 也不错
376页 隐含的this指针
icoding 2008-06-24
  • 打赏
  • 举报
回复
[Quote=引用 43 楼 taodm 的回复:]
就不要在语言的实现细节层面多话精力了,回头是岸。

什么是高质量的代码呢? 去看《代码大全》和《重构:改善既有代码设计》
[/Quote]

我觉得说这是两个层次,或者说两个方向的问题

无论写什么样的程序,我都需要写出高质量的代码,实现细节是通往底层的一条路
taodm 2008-06-24
  • 打赏
  • 举报
回复
就不要在语言的实现细节层面多话精力了,回头是岸。

什么是高质量的代码呢? 去看《代码大全》和《重构:改善既有代码设计》
icoding 2008-06-24
  • 打赏
  • 举报
回复
http://topic.csdn.net/u/20080128/20/29a82f12-f0bb-4078-8918-f33141fff40c.html

呵呵 不知道咋又被顶起来了,恩,上面的地址是我后续的文章,可以算是同一系列,有兴趣的可以瞧瞧,不过最近认识到继续把这些机制搞的很清楚,也不见得编写代码的水平就能提升,两个层次的事情吧,就算我要写编译器,我仍然面临着如何写出高质量代码的问题,不是底层了解的多就一定能写高质量的代码

PS:什么是高质量的代码呢?

简洁,逻辑清晰,容易修改
----------------
欢迎大家指点
guow043 2008-06-24
  • 打赏
  • 举报
回复
写的是什么代码,这也是c++
corsail 2008-06-24
  • 打赏
  • 举报
回复
深奥。。。
fangfei_119 2008-06-23
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 icoding 的回复:]
this指针在概念上可以理解为函数的参数,这个参数是隐藏的

[/Quote]
jzyshanxi 2008-06-23
  • 打赏
  • 举报
回复
草草看了一哈,觉得深奥,以后再看!!!
晨星 2008-06-23
  • 打赏
  • 举报
回复
[Quote=引用 38 楼 zhuangyu9999 的回复:]
楼主麻烦解释一下为什么this指针不占内存?sizeof运算符为什么看不到this所占的4字节内存?它到底是保存在哪的?
[/Quote]
this相当于非静态成员函数的一个隐函的参数,不占对象的空间。它跟对象之间没有包含关系,只是当前调用函数的对象被它指向而已。
所有成员函数的参数,不管是不是隐含的,都不会占用对象的空间,只会占用参数传递时的栈空间,或者直接占用一个寄存器。
zhuangyu9999 2008-06-23
  • 打赏
  • 举报
回复
楼主麻烦解释一下为什么this指针不占内存?sizeof运算符为什么看不到this所占的4字节内存?它到底是保存在哪的?
加载更多回复(35)

64,659

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧