const 引用:

在初始化常量引用时,允许用任意表达式作为初始值,只要该表达式的结果能转换成引用的类型即可。尤其,允许为一个常量引用绑定非常量的对象、字面值,甚至是一个表达式。我们来看 const 引用的分析:

#include <iostream>
int main(int argc, char* argv[])
{
const int &i = ;
return ;
}

该代码的汇编代码如下:

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 = ;
00964C9E mov dword ptr [ebp-14h],0Ch
00964CA5 lea eax,[ebp-14h]
00964CA8 mov dword ptr [i],eax return ;
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 ;
}

汇编结果:

    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 ;
000E4389 xor eax,eax
}

我们可以看到,这里也是生成了一个临时变量,步骤相当于如下:

const int temp = num;

const int &i = temp;

所以,如果 i 不是常量引用,那么就应该允许对 i 所绑定的对象进行修改,但是 temp 是一个临时变量,明显是一个右值,不合法。

当然,如果是这样的代码

int main(int argc, char* argv[])
{
const int num = ;
const int &i = num; return ;
}

那么就不需要一个中间变量。

于是这里就出现了一个很有趣的问题,当一个 const 引用绑定一个非常量对象的时候,其行为可能是不同的,比如如下:

int main(int argc, char* argv[])
{
double num = 23.9;
const int &i = num;
num = 54.9;
cout << i << endl; return ;
}

这份代码的结果是:23

而下面这份:

int main(int argc, char* argv[])
{
int num = ;
const int &i = num;
num = ;
cout << i << endl; return ;
}

结果是 54. 就是因为上面那份生成了一个中间变量的原因。

所以在使用 const 引用绑定非 const 变量的时候要注意这个问题。

const 引用的分析的更多相关文章

  1. C++ Const引用详解

    (1)       在实际的程序中,引用主要被用做函数的形式参数--通常将类对象传递给一个函数.引用必须初始化. 但是用对象的地址初始化引用是错误的,我们可以定义一个指针引用. 1 int ival ...

  2. C++引用和const引用、常量指针、指针常量

    1.引用.常量引用 引用主要被用做函数的形式参数--通常将类对象传递给一个函数. 引用在内部存放的是一个对象的地址,它是该对象的别名.引用不占用内存,因为取地址引用的值和被引用变量的地址相同.但是ob ...

  3. 临时变量不能作为非const引用

    转自:http://blog.csdn.net/u011068702/article/details/64443949 1.看代码 2.编译结果 3.分析和解决 就拿f(a + b)来说,a+b的值会 ...

  4. C++ const引用

    (1)       在实际的程序中,引用主要被用做函数的形式参数--通常将类对象传递给一个函数.引用必须初始化. 但是用对象的地址初始化引用是错误的,我们可以定义一个指针引用. 1 int ival ...

  5. 【c++基础】const、const指针、const引用

    一.const常量 声明时必须同时初始化(和“引用”一样) 二.const指针 三.const引用 引用本身和引用的对象都是const对象,可以用字面值来赋给const引用(普通引用则不行) ; co ...

  6. 传const引用代替传值

    1.为什么使用传const引用? a.被调方法中,形参不再进行copy构造,以及析构,提高效率. b.传值,会出现对象切割的问题. 2.有没有例外? 在编译器底层,引用是使用指针实现的.这就意味着,如 ...

  7. python的引用计数分析(二)

    python所有对象引用计数被减少1的情况: 一.对象的别名被赋予新的对象; a = 23345455 # 增加了一个引用 b = a # 增加了一个引用 print(sys.getrefcount( ...

  8. const引用

    在C++中可以声明const引用 const Type& name = var: const引用让变量拥有只读属性 const int &a = b const int &a ...

  9. c/c++ 拷贝控制 右值与const引用

    拷贝控制 右值与const引用 背景:当一个函数的返回值是自定义类型时,调用侧用什么类型接收?? 1,如果自定义类型的拷贝构造函数的参数用const修饰了:可以用下面的方式接收. Test t2 = ...

随机推荐

  1. BZOJ4755 JSOI2016扭动的回文串(二分答案+哈希)

    显然答案应该是由单串以某位置为中心的极长回文串继续在另一个串里拓展得到的.枚举中间位置二分答案,哈希判断即可.注意考虑清楚怎么处理偶回文,比如像manacher一样加分隔符. #include< ...

  2. kafka搭建笔记

    环境CentOS7.0,JDK1.8 一.下载安装 在kafka官网 http://kafka.apache.org/downloads下载到最新的kafka安装包 下载 2.0.0 release, ...

  3. [51nod1325]两棵树的问题

    description 题面 solution 点分治+最小割. 点分必选的重心,再在树上dfs判交,转化为最大权闭合子图. 可以做\(k\)棵树的情况. code #include<iostr ...

  4. bzoj1052: [HAOI2007]覆盖问题(二分+构造)

    貌似又写出了常数挺优(至少不劣)的代码>v< 930+人AC #49 写了个O(nlogn)貌似比一些人O(n)还快2333333 这题还是先二分答案,check比较麻烦 显然正方形一定以 ...

  5. 微信小程序 事件绑定 bind和catch 区别

    转自:https://blog.csdn.net/xiaoqiang_0719/article/details/79729592 本文以冒泡事件tap(手指触摸后马上离开,也就是点击事件)为例子来区别 ...

  6. 【神仙题】【P1600】【NOIP2016D1T2】天天爱跑步

    传送门 Description 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游 ...

  7. linux上修改系统默认语言设置

    locale命令设置语言环境(临时修改) [keysystem@localhost ~]$ date Fri Feb :: CST [keysystem@localhost ~]$ locale LA ...

  8. 清华大学计算机系大二 java 小学期考试题(摘自知乎)

    public class Main { public void test(Object o) { System.out.println("Object"); } public vo ...

  9. crontab使用进程锁解决冲突

    想到一个问题,如果在crontab里有个定时任务设置为一分钟执行一次,但是它执行的时间可能会超过一分钟,此时crontab一分钟后会再次运行该脚本吗?这样会不会出现冲突呢?网上找了下,说可以用Linu ...

  10. poj2060——Taxi Cab Scheme(最小路径覆盖)

    Description Running a taxi station is not all that simple. Apart from the obvious demand for a centr ...