关于C++引用的一些注意点
C++的引用首先跟指针的最大区别就是引用不是一个对象,而指针是一个对象;其次引用在其定义时就要初始化,而指针可以不用。
int val = ;
int &rval = val;
此时rval就绑定了val,其实就是rval就是val的一个别名。你修改了两个其中的一个,其值都会改变。
因为引用在一开始就初始化了,所以一个引用只能引用一个变量。还有,引用只能引用对象,也就是有地址的,不能是一个常数或者表达式。而且类型要匹配。
int &rval = ; //error: initializer must be an object
double dval = 3.14;
int &rdval = dval; //error: initializer must be an int object
References to const 常量引用
不同于非常量的引用,常量引用所引用的对象不能修改
const int ci = ;
const int &r1 = ci;
r1 = ; //error: r1 is a reference to const
int &r2 = ci; //error: nonconst reference to a const object
因为ci是一个常量,所以我们不能直接用一个引用来引用ci,因为我们不能修改ci。
上面提到引用要引用正确的自身的类型,但是常量引用可以引用一个非const的对象,一个数,或者表达式。
int i = ;
const int &r1 = i; //ok
const int &r2 = ; //ok
const int &r3 = r1 * ; //ok
int &r4 = r * ; //error: 非常量引用不能引用一个表达式
让我们想想这是为什么?
double dval = ;
const int &ri = dval; //ok
其实编译器帮我们多做了一步
double dval = ;
const int temp = dval; //创建一个暂时的常量对象来存放dval
const int &ri = temp; //将引用到这个暂时的常量
正因为有这个无名的中转存量,所以常量引用才可以引用数,表达式,还有不同类型的对象。
那为什么非常量引用就不能这样呢?
想想,刚才说的编译器帮我们弄了一个中转对象,其实我们引用是引用它,修改也修改它, 但它是无名的,也就是找不到地址,也无法找着。修改了也没用,我们是要修改dval(在上面列子中)。
所以说,只有常量引用才可以引用数字,表达式,不同类型的对象。因为我们不打算修改它,所以那个中转变量真的只是负责传递值,让常量引用初始化而已。(要是类型相同的话,就没有必要创建无名中转变量了,因为直接用来初始化都可以。感谢@Kvtis的指出)
最后一个例子
int i = ;
int &r1 = i;
const int &r2 = i;
r1 = ; //ok
r2 = ; //error
这样非常量引用和常量引用都引用一个值是可以的。非常量引用就不用说了,跟对象绑在一起,是别名,修改引用的同时也就修改了对象本身的内容。而常量引用,就是跟上面一样,编译器帮我们创建了一个无名的中转变量来储存,其实也就是赋值给常量对象初始化。你不能修改它就是了。
关于C++引用的一些注意点的更多相关文章
- 【.net 深呼吸】序列化中的“引用保留”
		假设 K 类中有两个属性/字段的类型相同,并且它们引用的是同一个对象实例,在序列化的默认处理中,会为每个引用单独生成数据. 看看下面两个类. [DataContract] public class 帅 ... 
- CSS 选择器及各样式引用方式
		Css :层叠样式表 (Cascading Style Sheets),定义了如何显示HTML元素. 目录 1. 选择器的分类:介绍ID.class.元素名称.符合.层次.伪类.属性选择器. 2. 样 ... 
- Android性能优化之巧用软引用与弱引用优化内存使用
		前言: 从事Android开发的同学都知道移动设备的内存使用是非常敏感的话题,今天我们来看下如何使用软引用与弱引用来优化内存使用.下面来理解几个概念. 1.StrongReference(强引用) 强 ... 
- C++中的引用
		一,C++中引用的基础知识 1.引用的基本概念 1.所谓的引用其实就是对变量起“别名”.引用和变量对应得是相同的内存,修改引用的值,变量的值也会改变,和指针类似. 2.引用在定义的时候必须要初始化,初 ... 
- Java 为值传递而不是引用传递
		——reference Java is Pass by Value and Not Pass by Reference 其实这个问题是一个非常初级的问题,相关的概念初学者早已掌握,但是时间长了还是容易 ... 
- EC笔记:第4部分:21、必须返回对象时,别返回引用
		使用应用可以大幅减少构造函数与析构函数的调用次数,但是引用不可以滥用. 如下: struct St { int a; }; St &func(){ St t; return t; } 在返回t ... 
- EC笔记:第4部分:20、传递引用代替传值
		考虑以下场景: #include <iostream> #include <string> using namespace std; struct Person { strin ... 
- 编译器开发系列--Ocelot语言2.变量引用的消解
		"变量引用的消解"是指确定具体指向哪个变量.例如变量"i"可能是全局变量i,也可能是静态变量i,还可能是局部变量i.通过这个过程来消除这样的不确定性,确定所引用 ... 
- C++右值引用浅析
		一直想试着把自己理解和学习到的右值引用相关的技术细节整理并分享出来,希望能够对感兴趣的朋友提供帮助. 右值引用是C++11标准中新增的一个特性.右值引用允许程序员可以忽略逻辑上不需要的拷贝:而且还可以 ... 
- 深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法)
		作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://zh.lucida.me/blog/java-8-lambdas-insideout-language- ... 
随机推荐
- yii 隐藏index.php的步骤
			Apache 1.开启apache的mod_rewrite模块 去掉LoadModule rewrite_module modules/mod_rewrite.so前的“#”符号 ... 
- StarlingMVC Framework  原理。。。
			向starlingmvc 中添加bean后..会根据Metadata标签,分别交给不同的Processor去处理...然后会执行每个bean的postConstruct函数.相当于初始化函数...可以 ... 
- android147 360  程序锁
			<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ... 
- MySQL 5.7 新特性大全和未来展望  图解
			本文转自微信公众号:高可用架构 作者:杨尚刚 引用 美图公司数据库高级 DBA,负责美图后端数据存储平台建设和架构设计.前新浪高级数据库工程师,负责新浪微博核心数据库架构改造优化,以及数据库相关的服务 ... 
- LINUX 内核文档地址
			Linux的man很强大,该手册分成很多section,使用man时可以指定不同的section来浏览,各个section意义如下: 1 - commands2 - system calls3 - l ... 
- 文本编辑器Nano实用快捷键
			一.复制.剪切和粘贴文本 1.行复制.剪切和粘贴 Alt+6:复制光标所在行. Ctrl+K:剪切光标所在行. Ctrl+U:粘贴. 2.自由复制.剪切和粘贴 自由复制: Ctrl+6:设置复制文本的 ... 
- LibSVM学习(四)——逐步深入LibSVM  转
			原文:http://blog.csdn.net/flydreamgg/article/details/4470121 其实,在之前上海交大模式分析与机器智能实验室对2.6版本的svm.cpp做了部分注 ... 
- cocos2d-x使用ant打包
			1. 下载apache-ant-1.9.3,然后添加环境变量ANT_HOME = D:\dev_envir\apache-ant-1.9.3(你自己的ant根目录),再在path中添加路径:%ANT_ ... 
- 给jdk写注释系列之jdk1.6容器(7)-TreeMap源码解析
			TreeMap是基于红黑树结构实现的一种Map,要分析TreeMap的实现首先就要对红黑树有所了解. 要了解什么是红黑树,就要了解它的存在主要是为了解决什么问题,对比其他数据结构比如数组,链 ... 
- jquery点击控制动画暂停开始
			一下是从w3c上面考下来了的, animation:[[ animation-name ] || [ animation-duration ] || [ animation-timing-functi ... 
