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,它是一个被自动解引用的指针,它的一系列引用操作由编译器来保证。

  • 相关阅读:
    HDU 5313 bitset优化背包
    bzoj 2595 斯坦纳树
    COJ 1287 求匹配串在模式串中出现的次数
    HDU 5381 The sum of gcd
    POJ 1739
    HDU 3377 插头dp
    HDU 1693 二进制表示的简单插头dp
    HDU 5353
    URAL 1519 基础插头DP
    UVA 10294 等价类计数
  • 原文地址:https://www.cnblogs.com/xiezhw3/p/3978861.html
Copyright © 2011-2022 走看看