C++下this指针实现机制分析(针对vc++ 6.0)

在C++编程中,this指针是经常需要用到,特别是形参与类结构成员具有相同名称时;我们都知道this是指向对象本身,那它是怎么实现呢?

先看一段源代码,如下:
#include <iostream>
using namespace std;

class people
{
public:
    int a;
    int b;
    people(int a, int b);
};

people::people(int a, int b)
{
    this->a = a;
    this->b = b;
}

int main()
{
    people e1(2, 3);
    return 0;
}

(1)main函数
从源代码中可以看到,在类people的构造函数people(int a, int b)有使用到this;先来看看main函数的汇编:
main:
00401080   push        ebp
00401081   mov         ebp,esp
00401083   sub         esp,48h
00401086   push        ebx
00401087   push        esi
00401088   push        edi
00401089   lea         edi,[ebp-48h]
0040108C   mov         ecx,12h
00401091   mov         eax,0CCCCCCCCh
00401096   rep stos    dword ptr [edi]
00401098   push        3
0040109A   push        2
0040109C   lea         ecx,[ebp-8]
0040109F   call        @ILT+0(people::people) (00401005)

004010A4   xor         eax,eax
004010A6   pop         edi
004010A7   pop         esi
004010A8   pop         ebx
004010A9   add         esp,48h
004010AC   cmp         ebp,esp
004010AE   call        __chkesp (004081a0)
004010B3   mov         esp,ebp
004010B5   pop         ebp
004010B6   ret

其中最主要的是上面蓝色部分,即people e1(2, 3);主要功能:
(1)参数压栈
(2)保存e1对象的地址到ecx;(即this指针的前身)
(3)call;
其中ILT是静态函数跳转的表,从汇编中可以看到上述源代码的ILT如下:
@ILT+0(??0people@@QAE@HH@Z):
00401005   jmp         people::people (00401030)
@ILT+5(?id@?$ctype@G@std@@$D):
0040100A   jmp         std::ctype<unsigned short>::id (00401110)
@ILT+10(?id@?$ctype@G@std@@$E):
0040100F   jmp         std::ctype<unsigned short>::id (004011b0)
@ILT+15(_main):
00401014   jmp         main (00401080)

(2)构造函数people
下面进入people构造函数,反汇编如下:
people::people:
00401030   push        ebp
00401031   mov         ebp,esp
00401033   sub         esp,44h
00401036   push        ebx
00401037   push        esi
00401038   push        edi
00401039   push        ecx
0040103A   lea         edi,[ebp-44h]
0040103D   mov         ecx,11h
00401042   mov         eax,0CCCCCCCCh
00401047   rep stos    dword ptr [edi]
00401049   pop         ecx
0040104A   mov         dword ptr [ebp-4],ecx

0040104D   mov         eax,dword ptr [ebp-4]
00401050   mov         ecx,dword ptr [ebp+8]
00401053   mov         dword ptr [eax],ecx

00401055   mov         edx,dword ptr [ebp-4]
00401058   mov         eax,dword ptr [ebp+0Ch]
0040105B   mov         dword ptr [edx+4],eax

0040105E   mov         eax,dword ptr [ebp-4]
00401061   pop         edi
00401062   pop         esi
00401063   pop         ebx
00401064   mov         esp,ebp
00401066   pop         ebp
00401067   ret         8

在讲解之前,先来看看执行到“00401039   push        ecx”时堆栈的布局:



通过main函数可以知道,对象e1的地址是保存在ecx中,于是:
00401039   push        ecx
。。。
00401049   pop         ecx
0040104A   mov         dword ptr [ebp-4],ecx

就是把ecx的值赋给[ebp-4],即上图this所在的位置;到这里我们就清楚了this的来历;

下面的3句汇编是实现this->a = a;

0040104D   mov         eax,dword ptr [ebp-4]
00401050   mov         ecx,dword ptr [ebp+8]
00401053   mov         dword ptr [eax],ecx


下面的3句汇编是实现this->b = b;

00401055   mov         edx,dword ptr [ebp-4]
00401058   mov         eax,dword ptr [ebp+0Ch]
0040105B   mov         dword ptr [edx+4],eax

总结:
通过上述分析,可以知道,this指针就是存放在当前成员函数的[ebp-4]位置;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值