aihot  2020-11-12 09:25:31  OpenCV |   查看评论   

 C++的那些事:你真的了解引用吗

一、引用的本质是什么

说到引用,一般C++的教材中都是这么定义的:

1,引用就是一个对象的别名。

2,引用不是值不占内存空间。

3,引用必须在定义时赋值,将变量与引用绑定。

那你有没有想过,上面的定义正确吗?编译器是如何解释引用的?

这里先给出引用的本质定义,后面我们再进一步论证。

1,引用实际是通过指针实现的。

2,引用是一个常量指针。

3,引用在内存中占4个字节。

4,在对引用定义时,需要对这个常量指针初始化。

二、探究本质

我们从最简单的变量的定义开始,看编译器会做哪些事情。

int var = 42; mov         dword ptr [var],2Ah  // 对应汇编

上面语句申请了一块内存空间,占4个字节,存放了一个int型的变量。内存里放的是42的二进制码。

汇编代码向我们表达的意思就是把42写入以var为地址的内容区域。var有点像我们理解上的指针,只是编译器并没有把它抽象出来,而是让我们更表象的理解:申请一个变量,它的值为42。

那么var这个变量名放在哪呢

我们知道如果访问内存里的数据,需要通过地址来进行访问,所以上面的代码在经过编译器生成目标代码时,用存放42的地址了所有的var,所以结论时,目标文件中不存在var,所以变量名本身是不占内存的

而我们知道,引用是变量的一个别名。那么,从这很多人会联想到,引用会不会也只是一个名字而已,编译器在生成目标代码的时候,会用实际地址替换引用呢?

答案并非这样!

那我们接下来看看,当我们定义一个引用时,发生了什么:

1     int var = 42; 
2 01303AC8  mov         dword ptr [var],2Ah   3     int&  refVar = var; 
4 01303ACF  lea         eax,[var]   5 01303AD2  mov         dword ptr [refVar],eax 

上面的代码显示,当定义一个引用时,编译器将var的地址赋给了以refVar为地址的一块内存区域。也就是说refVar其实存放的是var的地址。

这让我们联想到了指针,那么我们看看定义一个指针是发生了什么:

1     int var = 42; 
2 01213AC8  mov         dword ptr [var],2Ah   3     int* ptrVar = &var; 
4 01213ACF  lea         eax,[var]   5 01213AD2            
          
 

除特别注明外,本站所有文章均为 赢咖4注册 原创,转载请注明出处来自C++的那些事:你真的了解引用吗

留言与评论(共有 0 条评论)
   
验证码:
[lianlun]1[/lianlun]