关于this指针的思考

关于this指针的思考


this指针的引入

我们都知道,在面向对象的设计中,类的成员方法可以随意访问同样存储方式的成员变量。
比如:

class Test
{
    int na;

public:
    void fun()
    {
        na = 4; // 访问成员变量

        printf("%d\n",na);
        return;
    }
};  

在Test类中,fun函数可以访问na,那么在使用该方法的时候是如何找到成员变量的地址的呢?

this指针的汇编解释

Test * pTT = new Test();
pTT->fun();

我们按照程序员的习俗先来看看反汇编

    pTT->fun();
00E3237F  mov         ecx,dword ptr [pTT]  
00E32382  call        Test::fun (0E311E5h)

可以看到,先把当前对象的地址放在ecx寄存器中,然后进入fun函数入口表。
fun中的反汇编内容如下:

00E329D0  push        ebp  // 栈底指针压栈
00E329D1  mov         ebp,esp  //把栈顶作为新的栈底
00E329D3  sub         esp,0CCh  //开辟出0CCh个字节单元,作为程序的交换数据区,及204个字节
00E329D9  push        ebx  // 压栈ebx
00E329DA  push        esi  // 压栈esi
00E329DB  push        edi  // 压栈edi
00E329DC  push        ecx  // 压栈ecx
00E329DD  lea         edi,[ebp-0CCh] //把ebp-0cch的值赋给edi,即最开始申请到的204个字节的首地址 
00E329E3  mov         ecx,33h  //作为rep的循环次数, 33h = 51; 51 * 4 = 204
00E329E8  mov         eax,0CCCCCCCCh  // 初始化内容
00E329ED  rep stos    dword ptr es:[edi]  //把204个字节用cc初始化,执行完后edi前进到栈底的位置,edi = ebx
00E329EF  pop         ecx  // 取出ecx
00E329F0  mov         dword ptr [this],ecx  // 原始的反汇编是mov [edi-8],ecx,也就是说把edi-8处的内存空间作为this,保存的对象首地址,或者说是ebp-8为首地址
    16:         na = 4; 
00E329F3  mov         eax,dword ptr [this] // 对象的首地址用[this]表示  
00E329F6  mov         dword ptr [eax],4  // 通过[eax+n]的方式取出对象中的每一个元素。

总结

在用对象的指针调用对象的方法时,会把该对象的首地址保存在ecx寄存器中,然后在程序执行时,先在栈中开辟一段内存空间(大小根据具体情况而定),然后把[ebp-8]作为this 指针变量。

扩展

在面向对象中,我们说方法和属性是一个整体,他们一起描述一个对象。所以,在方法中理所当然的可以随意使用自己的属性。但是在考虑如何用编译器实现这样语法时,就有许多不同的方法了。this 指针只是对实现这一功能的一种笼统描述。上面的例子是C++中this 指针的实现方法,我们可以考虑一下如果不用这种方法,还可以如何实现this 指针?
比如说,1、把对象的指针作为函数的第一个参数,在调用函数的时候先进行压栈,然后在函数里面使用,函数调用完成后,由调用者释放空间。
2、在函数的第一行添加一个this指针定义,同样在调用前把对象的指针保存在ecx中,然后执行函数的时候把ecx赋值给this,使用完成后由被调用者来释放。

当然我们在使用的时候,可以统一把他们作为函数的局部变量来使用,在VS 编译器中就是这样做的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值