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++引用的一些注意点的更多相关文章

  1. 【.net 深呼吸】序列化中的“引用保留”

    假设 K 类中有两个属性/字段的类型相同,并且它们引用的是同一个对象实例,在序列化的默认处理中,会为每个引用单独生成数据. 看看下面两个类. [DataContract] public class 帅 ...

  2. CSS 选择器及各样式引用方式

    Css :层叠样式表 (Cascading Style Sheets),定义了如何显示HTML元素. 目录 1. 选择器的分类:介绍ID.class.元素名称.符合.层次.伪类.属性选择器. 2. 样 ...

  3. Android性能优化之巧用软引用与弱引用优化内存使用

    前言: 从事Android开发的同学都知道移动设备的内存使用是非常敏感的话题,今天我们来看下如何使用软引用与弱引用来优化内存使用.下面来理解几个概念. 1.StrongReference(强引用) 强 ...

  4. C++中的引用

    一,C++中引用的基础知识 1.引用的基本概念 1.所谓的引用其实就是对变量起“别名”.引用和变量对应得是相同的内存,修改引用的值,变量的值也会改变,和指针类似. 2.引用在定义的时候必须要初始化,初 ...

  5. Java 为值传递而不是引用传递

    ——reference Java is Pass by Value and Not Pass by Reference 其实这个问题是一个非常初级的问题,相关的概念初学者早已掌握,但是时间长了还是容易 ...

  6. EC笔记:第4部分:21、必须返回对象时,别返回引用

    使用应用可以大幅减少构造函数与析构函数的调用次数,但是引用不可以滥用. 如下: struct St { int a; }; St &func(){ St t; return t; } 在返回t ...

  7. EC笔记:第4部分:20、传递引用代替传值

    考虑以下场景: #include <iostream> #include <string> using namespace std; struct Person { strin ...

  8. 编译器开发系列--Ocelot语言2.变量引用的消解

    "变量引用的消解"是指确定具体指向哪个变量.例如变量"i"可能是全局变量i,也可能是静态变量i,还可能是局部变量i.通过这个过程来消除这样的不确定性,确定所引用 ...

  9. C++右值引用浅析

    一直想试着把自己理解和学习到的右值引用相关的技术细节整理并分享出来,希望能够对感兴趣的朋友提供帮助. 右值引用是C++11标准中新增的一个特性.右值引用允许程序员可以忽略逻辑上不需要的拷贝:而且还可以 ...

  10. 深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法)

    作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://zh.lucida.me/blog/java-8-lambdas-insideout-language- ...

随机推荐

  1. 为CentOS 加入�本地源

    首先把光盘中的Packages文件夹复制到本地. [arm@Jarvis Packages]$ pwd /home/Packages 安装用于创建安装包依赖关系的软件createrepo. [arm@ ...

  2. asp.net常用函数

    ASP.NET网络编程中常用到的27个函数集 Abs(number) 取得数值的绝对值.   Asc(String) 取得字符串表达式的第一个字符ASCII 码.   Atn(number) 取得一个 ...

  3. php中var_export与var_dump的区别分析

    一 var_dump (PHP 3 >= 3.0.5, PHP 4, PHP 5) var_dump -- 打印变量的相关信息 描述 void var_dump ( mixed expressi ...

  4. javascript获取鼠标位置

    首先不同浏览器中event位置属性的分析: 1. IE的event.x,event.y是以事件触发元素的父元素外界为参考点(不包括滚动距离) 2. Firefox的event.pageX,event. ...

  5. 超级强大的vim配置(vimplus)

    vimplus vimplus是vim的超级配置安装程序 github地址:https://github.com/chxuan/vimplus.git,欢迎star和fork. 接触vim到现在也有几 ...

  6. Java设计模式11:常用设计模式之代理模式(结构型模式)

    1. Java之代理模式(Proxy Pattern) (1)概述: 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问. 在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象 ...

  7. win10 IIS10 HTTP 错误 404.2 - Not Found

    环境win10系统IIS10里边发布web应用程序的时候,出现 HTTP 错误 404.2 - Not Found 由于 Web 服务器上的“ISAPI 和 CGI 限制”列表设置,无法提供您请求的页 ...

  8. LeetCode 268

    Missing Number Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one ...

  9. Wince 设备环境和画笔应用

    本文主要讲到的是画笔应用,在Wince -06环境下,画笔应用很广泛,很有技巧,这里笔者要着重介绍. 设备环境可以用一下图表示,主要是让大家大致了解Wince -06的设备环境,下面在图形舍虚设计中会 ...

  10. hdu 4325 树状数组+离散化

    思路:这题的思路很容易想到,把所有时间点离散化,然后按时间一步一步来,当到达时间i的时候处理所有在i处的查询. 这个代码怎一个挫字了得 #include<iostream> #includ ...