首页 > 代码库 > const 引用的分析
const 引用的分析
const 引用:
在初始化常量引用时,允许用任意表达式作为初始值,只要该表达式的结果能转换成引用的类型即可。尤其,允许为一个常量引用绑定非常量的对象、字面值,甚至是一个表达式。我们来看 const 引用的分析:
#include <iostream>int main(int argc, char* argv[]){ const int &i = 12; return 0;}
该代码的汇编代码如下:
int main(int argc, char* argv[]){00964C80 push ebp 00964C81 mov ebp,esp 00964C83 sub esp,0D8h 00964C89 push ebx 00964C8A push esi 00964C8B push edi 00964C8C lea edi,[ebp-0D8h] 00964C92 mov ecx,36h 00964C97 mov eax,0CCCCCCCCh 00964C9C rep stos dword ptr es:[edi] const int &i = 12;00964C9E mov dword ptr [ebp-14h],0Ch 00964CA5 lea eax,[ebp-14h] 00964CA8 mov dword ptr [i],eax return 0;00964CAB xor eax,eax }
我们可以看到,const 引用绑定一个12的时候,相当于有如下的步骤:
int temp = 12;
const int &i = temp;
我们上面分析过,引用实质上是一个指针,绑定一个对象就是保存对象的地址,那么一个12是没有地址的,所以需要一个临时变量。当然如果那个常量本身有地址,那么久直接将其地址保存到引用的内存空间。
下面考虑一个常量引用绑定到另一种类型时发生了什么:
int main(int argc, char* argv[]){ double num = 23.2; const int &i = num; return 0;}
汇编结果:
double num = 23.2;000E436E movsd xmm0,mmword ptr ds:[0ECD80h] double num = 23.2;000E4376 movsd mmword ptr [num],xmm0 const int &i = num;000E437B cvttsd2si eax,mmword ptr [num] 000E4380 mov dword ptr [ebp-24h],eax 000E4383 lea ecx,[ebp-24h] 000E4386 mov dword ptr [i],ecx return 0;000E4389 xor eax,eax }
我们可以看到,这里也是生成了一个临时变量,步骤相当于如下:
const int temp = num;
const int &i = temp;
所以,如果 i 不是常量引用,那么就应该允许对 i 所绑定的对象进行修改,但是 temp 是一个临时变量,明显是一个右值,不合法。
当然,如果是这样的代码
int main(int argc, char* argv[]){ const int num = 23; const int &i = num; return 0;}
那么就不需要一个中间变量。
于是这里就出现了一个很有趣的问题,当一个 const 引用绑定一个非常量对象的时候,其行为可能是不同的,比如如下:
int main(int argc, char* argv[]){ double num = 23.9; const int &i = num; num = 54.9; cout << i << endl; return 0;}
这份代码的结果是:23
而下面这份:
int main(int argc, char* argv[]){ int num = 23; const int &i = num; num = 54; cout << i << endl; return 0;}
结果是 54. 就是因为上面那份生成了一个中间变量的原因。
所以在使用 const 引用绑定非 const 变量的时候要注意这个问题。
const 引用的分析
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。