您的位置:首页 > 编程语言 > C语言/C++

深入理解C++中的常量引用

2014-05-30 15:01 197 查看
在笔者的上篇文章《一个有趣的程序:C++运算符重载中的“指鹿为马”》中,细心的读者可能会发现,这个函数 void listen(const Horse &h)
的参数必须为常量引用(即const Horse &h)才能够使程序正常运行出预料的结果,下面就来解释一个问什么必须用常量引用作为其参数,并一起探讨常量引用。

一.概念

所谓常量引用,就是“对const”的引用,与普通引用不同的是,对常量的引用不能被用作修改它所绑定的对象。

举个列子:

const int i = 2014;

const int &ii = i; //引用及其对象都是常量

int i = 10;

const int &a = i; //将const int& 绑定到一个普通的int对象上

在这个例子中,常量引用a一旦绑定i,便不能通过a改变i的值。“常量”体现在“不能修改”。



二.特殊之处

C++中引用的类型必须与其所引用的对象一致且必须为一个左值,但读者可能已经注意到了,笔者所给第二条的例子并不符合这条规则,这正是常量引用的特殊之处和其魅力所在。

初始化常量引用时,允许任意表达式作为其初值,只要该表达式的结果能够转化成引用的类型即可,是不是很强大



举个几个例子:

int a = 8;

const int &b = a;

const int &c = 9;

const double &d = a*2;

三.原因

初始化常量引用时编译器首先建立一个临时对象,然后将该临时变量绑定到该常量引用,对常量引用的操作就是对该临时变量的操作(但实际上”常量“的限制导致无法对这个临时变量进行操作)。故常量引用绑定的是”副本“(临时变量)而不是”母体“(愿对象)。

举个例子帮助理解:

double d = 6;

const int &i = d;

上面这段代码经过编译器处理后,变成了这样:

double d = 6;

const int temp = (int)d; //由双精度浮点数d生成一个临时的整型常量

const int &i = temp; //让i绑定这个临时常量d

那么,假设i不是常量(即改为int &i时),执行int &i = d;会出现什么后果呢?答案是编译会报错!!

为什么??


如果i不是常量,就允许对i赋值,这样就能够改变i所引用对象d的值。而此时绑定的对象是一个临时对象而非原对象d,这样就无法通过i来改变d的值啦!既然程序员让i引用d,就肯定是想要通过i来改变d的值,显然,临时变量的出现使得引用失去了其原本的意义,所以C++语言也就把这种行为归为非法!


四.注意

对const的引用可能引用一个并非const的对象,也就是说,常量引用仅仅对引用可参与的操作做出了限定,对于引用对象本身是不是一个常量并未做限定。

举几个个列子:

int i = 10;

int &i1 = i; //允许通过i1来修改i的值

const int &i2 = i; //i不是一个常量,但是不允许通过i2来修改i的值

不允许用过i2修改i的值,但是可以通过其他路径修改i的值,既可以给i直接赋值,也可以像i1一样绑定到i的其他引用来修改!

这时候再去看笔者的上一个程序中的listen函数,是不是容易理解了呢?


当然,这篇文章只是帮助大家理解,常量引用还有更多的用法,欢迎大家补充交流!










参考资料:《C++Primer》

博客《C++的常量引用》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: