zoukankan      html  css  js  c++  java
  • c++ 引用的分析

       在一般教材里面,我们会说引用是变量的别名,另外在 c++ primer 5里面说到引用的时候,说引用不是对象,不能对它进行取地址。但是我们来看看下面代码的分析:

     1 #include <iostream>
     2 
     3 int main(int argc, char* argv[])
     4 {
     5     int i = 90;
     6     int &qi = i;
     7     int *pqi = &(&qi);
     8     int *pi = &i;
     9 
    10     return 0;
    11 }

    汇编结果:

     1 #include <iostream>
     2 
     3 int main(int argc, char* argv[])
     4 {
     5 00BC4350  push        ebp  
     6 00BC4351  mov         ebp,esp  
     7 00BC4353  sub         esp,0F0h  
     8 00BC4359  push        ebx  
     9 00BC435A  push        esi  
    10 00BC435B  push        edi  
    11 00BC435C  lea         edi,[ebp-0F0h]  
    12 00BC4362  mov         ecx,3Ch  
    13 00BC4367  mov         eax,0CCCCCCCCh  
    14 00BC436C  rep stos    dword ptr es:[edi]  
    15     int i = 90;
    16 00BC436E  mov         dword ptr [i],5Ah  // wc: 将90 保存到 i 的内存单元 
    17     int &qi = i;
    18 00BC4375  lea         eax,[i]  
    19 00BC4378  mov         dword ptr [qi],eax  // wc: 将 i 的地址保存到 qi 的内存单元,这里可以说明引用也是有自己的内存空间的,
    20                                           // wc: 它用来保存所绑定的对象的地址
    21     int *pqi = &qi;
    22 00BC437B  mov         eax,dword ptr [qi]
    23 00BC437E  mov         dword ptr [pqi],eax  // wc: 这里是将引用取地址给一个指针,我们可以看到,实际上是将 qi 内存单元里的值保存到 pqi 的内存单元,
    24                                            // wc: 那么也就说,对一个引用取地址实际上是对其取值,取出它保存的所绑定对象的地址
    25                                            // wc: 这也就说明了为什么对一个引用取地址得到的是指向其所绑定对象
    26     int *pi = &i;
    27 00BC4381  lea         eax,[i]  
    28 00BC4384  mov         dword ptr [pi],eax  // wc: 将 i 的地址保存到 pi 的内存单元,这个是一般的对一个对象取地址
    29 
    30     return 0;
    31 00BC4387  xor         eax,eax  
    32 }

    这么来说,引用的内部实现可能是常量指针,这样引用就是一个可以被自动解引用的指针。

    表达式   int &qi = i; 将会被编译器转化成 int *const qi = &i; 而引用之所以要初始化是因为 const 类型变量必须初始化,这个指针也必须指向。我们还可以以另外一个程序来证明:

     1  #include <iostream>                                       
     2  using namespace std;                                      
     3                                                            
     4  struct Tq {                                               
     5     int &i;                                                
     6     double &j;                                             
     7  };                                                        
     8                                                            
     9  int main(int argc, char* argv[])                          
    10  {                                                         
    11int *ptr;                                             
    12     ┊cout << "size of pointer: " << sizeof(ptr) << endl;                                                                                                                                                    
    13     ┊cout << "size of Tq: " << sizeof(Tq) << endl;         
    14                                                            
    15return 0;                                          
    16                                                            
    17  } 

    运行结果:

    size of pointer: 8

    size of Tq: 16

    可以看出,两个引用其实就是两个指针。而不是像书上说的引用不是对象。

    以上的结果都说明,引用其实就是一个指针,基于引用一定要初始化和不能改变绑定,引用的实现应该是 const pointer,它是一个被自动解引用的指针,它的一系列引用操作由编译器来保证。

  • 相关阅读:
    Cookie笔记
    Java中Scanner类
    Java 位运算(移位、位与、或、异或、非)
    Python:urllib和urllib2的区别
    Scrapy在win7 32位的安装及依赖包
    [转] Windows下使用Python读取Excel表格数据
    python sort()和sorted()方法
    flask开发遇到 Must provide secret_key to use csrf解决办法
    flask开发遇到Internal Server Error的解决办法
    Android开发之消息机制
  • 原文地址:https://www.cnblogs.com/xiezhw3/p/3978861.html
Copyright © 2011-2022 走看看