const 引用的分析
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 引用的分析的更多相关文章
- C++ Const引用详解
(1) 在实际的程序中,引用主要被用做函数的形式参数--通常将类对象传递给一个函数.引用必须初始化. 但是用对象的地址初始化引用是错误的,我们可以定义一个指针引用. 1 int ival ...
- C++引用和const引用、常量指针、指针常量
1.引用.常量引用 引用主要被用做函数的形式参数--通常将类对象传递给一个函数. 引用在内部存放的是一个对象的地址,它是该对象的别名.引用不占用内存,因为取地址引用的值和被引用变量的地址相同.但是ob ...
- 临时变量不能作为非const引用
转自:http://blog.csdn.net/u011068702/article/details/64443949 1.看代码 2.编译结果 3.分析和解决 就拿f(a + b)来说,a+b的值会 ...
- C++ const引用
(1) 在实际的程序中,引用主要被用做函数的形式参数--通常将类对象传递给一个函数.引用必须初始化. 但是用对象的地址初始化引用是错误的,我们可以定义一个指针引用. 1 int ival ...
- 【c++基础】const、const指针、const引用
一.const常量 声明时必须同时初始化(和“引用”一样) 二.const指针 三.const引用 引用本身和引用的对象都是const对象,可以用字面值来赋给const引用(普通引用则不行) ; co ...
- 传const引用代替传值
1.为什么使用传const引用? a.被调方法中,形参不再进行copy构造,以及析构,提高效率. b.传值,会出现对象切割的问题. 2.有没有例外? 在编译器底层,引用是使用指针实现的.这就意味着,如 ...
- python的引用计数分析(二)
python所有对象引用计数被减少1的情况: 一.对象的别名被赋予新的对象; a = 23345455 # 增加了一个引用 b = a # 增加了一个引用 print(sys.getrefcount( ...
- const引用
在C++中可以声明const引用 const Type& name = var: const引用让变量拥有只读属性 const int &a = b const int &a ...
- c/c++ 拷贝控制 右值与const引用
拷贝控制 右值与const引用 背景:当一个函数的返回值是自定义类型时,调用侧用什么类型接收?? 1,如果自定义类型的拷贝构造函数的参数用const修饰了:可以用下面的方式接收. Test t2 = ...
随机推荐
- Square Root of Permutation - CF612E
Description A permutation of length n is an array containing each integer from 1 to n exactly once. ...
- CF757G Can Bash Save the Day?
CF757G Can Bash Save the Day? #include<bits/stdc++.h> #define RG register #define IL inline #d ...
- BZOJ3894:文理分科——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=3894 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠结过) 小P所在的班级要进行文理 ...
- HDU3480:Division——题解
http://acm.hdu.edu.cn/showproblem.php?pid=3480 将一列数划分成几个集合,这些集合的并集为该数列,求每个数列的(最大值-最小值)^2的和的最小值. 简单的d ...
- 洛谷 P1841 [JSOI2007]重要的城市 解题报告
P1841 [JSOI2007]重要的城市 题目描述 参加jsoi冬令营的同学最近发现,由于南航校内修路截断了原来通向计算中心的路,导致去的路程比原先增加了近一公里.而食堂门前施工虽然也截断了原来通向 ...
- float,absolute脱离文档流的总结
dom元素脱离文档流,有如下几种方式: 1. float 脱离文档流,其他dom元素无视他,在其下方布局,但是其未脱离文本流,其他元素的文本会认为他存在,环绕他布局.父元素会无视他,因此无法获取其高度 ...
- 【状压DP】【UVA11825】 Hackers' Crackdown
传送门 Description 你是一个hacker,侵入了一个有着n台计算机(编号为1.2.3....n)的网络.一共有n种服务,每台计算机都运行着所有服务.对于每台计算机,你都可以选择一项服务,终 ...
- 爬虫实例——爬取淘女郎相册(通过selenium、PhantomJS、BeautifulSoup爬取)
环境 操作系统:CentOS 6.7 32-bit Python版本:2.6.6 第三方插件 selenium PhantomJS BeautifulSoup 代码 # -*- coding: utf ...
- Qt中内存泄露和退出崩溃的问题 delete
Qt中帮程序员做了一些内存回收的事情,但正因为这些反而让对此不熟悉的人会屡屡犯错. 收录一篇不错的文章: 在C++中学习过程中,我们都知道: delete 和 new 必须 配对使用(一 一对应):d ...
- mysql连接时权限问题 用户问题
启动工程时会连接mysql数据库,此时报错: ERROR 1044 (42000): Access denied for user 'pay'@'localhost' to database 'pay ...