c++中引用和指针的内部实现

来源:互联网 发布:如何调试动态加载的js 编辑:程序博客网 时间:2024/06/11 22:00

c++中,引用和指针时比较让人混淆的。它们的外在区别想必很多人都知道。在这我再重复一下。

引用在定义时必须初始化,即该引用所引用的必须时确实存在的变量,不能为NULL。而指针就没有这个限制。有人说,引用就相当于一个变量的别名,对该引用所做的操作就相当于对原变量一样。我不太认同这个看法。在内部实现上,其实引用也是通过地址实现的。因此我更想称引用为一种特殊的指针。让我们看看下面这个简单的例子。

#include<iostream.h>

int main()
{
int a=1;
int b=2;
int &c=a;
int *d=&b;
c=*d;
cout<<a<<endl;
cout<<c<<endl;
return 0;

}

反汇编代码如下:

1:    #include<iostream.h>
2:
3:    int main()
4:    {
00401040   push        ebp
00401041   mov         ebp,esp
00401043   sub         esp,50h
00401046   push        ebx
00401047   push        esi
00401048   push        edi
00401049   lea         edi,[ebp-50h]
0040104C   mov         ecx,14h
00401051   mov         eax,0CCCCCCCCh
00401056   rep stos    dword ptr [edi]
5:        int a=1;
00401058   mov         dword ptr [ebp-4],1
6:        int b=2;
0040105F   mov         dword ptr [ebp-8],2
7:        int &c=a;
00401066   lea         eax,[ebp-4]              !注意这里,把ebp-4赋给eax,ebp-4即为变量a的地址
00401069   mov         dword ptr [ebp-0Ch],eax !把eax 存储在ebp-0Ch这个位置,ebp-0Ch为引用c的位置
8:        int *d=&b;
0040106C   lea         ecx,[ebp-8]            
0040106F   mov         dword ptr [ebp-10h],ecx !这两行和上面的两行是一模一样的
9:        c=*d;                    !把b 的值赋给c
00401072   mov         edx,dword ptr [ebp-0Ch] !把a的地址给edx
00401075   mov         eax,dword ptr [ebp-10h] !把b的地址给eax
00401078   mov         ecx,dword ptr [eax]           !把b的值给ecx
0040107A   mov         dword ptr [edx],ecx           !把ecx 即b的值给a,c引用的还是a
10:       cout<<a<<endl;
0040107C   push        offset @ILT+10(endl) (0040100f)
00401081   mov         edx,dword ptr [ebp-4]
00401084   push        edx
00401085   mov         ecx,offset cout (004299c0)
0040108A   call        ostream::operator<< (00401230)
0040108F   mov         ecx,eax
00401091   call        @ILT+0(ostream::operator<<) (00401005)
11:       cout<<c<<endl;
00401096   push        offset @ILT+10(endl) (0040100f)
0040109B   mov         eax,dword ptr [ebp-0Ch]
0040109E   mov         ecx,dword ptr [eax]
004010A0   push        ecx
004010A1   mov         ecx,offset cout (004299c0)
004010A6   call        ostream::operator<< (00401230)
004010AB   mov         ecx,eax
004010AD   call        @ILT+0(ostream::operator<<) (00401005)
12:       return 0;
004010B2   xor         eax,eax
13:
14:   }
004010B4   pop         edi
004010B5   pop         esi
004010B6   pop         ebx
004010B7   add         esp,50h
004010BA   cmp         ebp,esp
004010BC   call        __chkesp (00403650)
004010C1   mov         esp,ebp
004010C3   pop         ebp
004010C4   ret

可见,在内部实现上,引用和指针是一模一样的,对引用的更改,就是把引用所指的变量重新赋指,引用本身并没有更改。

原创粉丝点击