关于引用&

这个部分涉及到引用的原理性描述还是涉及到需要理解的部分的。

问题出现在当你向一个本来形参是一个引用的函数里面传参数时,你传的并不是一个具体的数值,而是一个表达式,这会出现一个什么样的结果呢?C++ Primer Plus中说大部分编译器会告诉你这是个错误,我验证了一下,还真是个错误,如下图所示:


那这是为啥呢?那是因为一个函数形参最终还是只会接收一个实参而不是表达式,那么这个表达式就会计算出一个中间值,然后形参中的引用就会指向这个中间值,因为中间值是临时性的,用完了就没了,而一个引用不能指向一个稍纵即逝的变量,所以它会报错。

但是,如果在形参列表中加上const使之成为const引用,那就可以正常运行了,如下图所示:


那么为什么在这种情况下就可以了呢?想知道答案必须先知道一个新词,叫lvalue,那什么叫lvalue呢?它是一个能够取得地址的数据对象,在C语言中通常被称为左值,因为它们有个确切的地址。而那些文字常量和表达式则属于非左值。而编译器产生中间值只在下面两个情况下。

1、实参类型就是形参类型,但是它不能作为左值,换句话说它只有一个临时性的地址可供访问。

2、实参类型和形参类型不匹配,但是它能够转换成形参类型。

一个形参是const引用只有在上面两种情况下才会产生中间值,而这个中间值的生命期也只是函数的生存期而已。C++认为非const代表你想去改变值,const代表你想只读值。这是合理的,因为你使用const去修饰形参很显然就是想在函数中只读取实参的值,只是去使用它,而不想做别的。所以在这种情况下即使产生中间值也是合法的,合理的。那么这就可以解释为什么非const引用不能接受表达式实参了,因为生成的中间值是临时性质的,对这个中间值进行更改必然不会影响到真正的实参,而你使用非const引用的很大目的就是去改变实参,这就不符合你的初衷了,所以在上述两种情况下也就会报错了。看下面的例子:


推荐阅读更多精彩内容

  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy阅读 8,304评论 1 52
  • 总体上必须清楚的:1)程序结构是三种: 顺序结构 , 循环结构(三个循环结构), 选择结构(if 和 switch...
    静熙老师哈哈哈阅读 610评论 1 20
  • 收集非原创文章,如遇原作者,请私聊我,我会表明出处! 1--10 1. C++中什么数据分配在栈或堆,静态存储区以...
    Juinjonn阅读 4,479评论 0 30
  • C++右值引用 右值引用应该是C++11引入的一个非常重要的技术,因为它是移动语义(Move semantics)...
    小白将阅读 1,809评论 2 10
  • 是最近才发现的简书这个软件,看过几篇文章,每每看到一篇触动心弦的文章,心里总有种感觉和欲望要破土而出。而此时此...
    小小鱼饵儿阅读 178评论 0 1
  • 剑光断夜阅读 46评论 0 0
  • 第二十天 气温越来越高 记忆却越来越淡 漫步 乡间陌生的小路 接近八点的夜 晚风停了 大雁也过了 屋里的灯亮了 繁...
    柚子与诗阅读 69评论 0 2
  • 些日子,顽皮掏蛋的我不改顽皮掏蛋的风采,该大大咧咧,风风火火本性照样吃香喝辣(特别提醒本人吃辣不行!!),上课下...
    LeeWeee阅读 50评论 0 0