关于const reference的疑惑

囧豆粉 2011-06-08 10:35:04
C++中const reference的奇怪问题

在<C++ Primer>第四版中说,const Reference is a Reference To const (P.60)。

而这里有种情况:

int i = 2000;

const int &refI = i; //i不是const,但refI是。

++i;

程序输出的结果,refI的值为2001.也就是说, refI的值被通过另一种途径(++i)改变了。这种写法与“const Reference is a Reference To const”的说法相悖。而且,明明是const,却被改变了,有点。。。

用的是gnu c++编译器= =。至于微软的编译器,还没有测试过。。。

这种情况书上并没有提到,既没有否认也没有肯定这种写法的正确与否。

书上倒是给了另一种情况:

double dval = 3.14;

const int &ri = dval;

经测试,在这种情况下,对dval的值的改变并不影响ri的值。(书上对此没有明确的说明)

因为这种情况实际相当于--


double dval = 3.14;

int temp = dval;

const int &ri = temp;


跟ri有关系的,只有temporary variable而已,这东西在使用完毕大概就销毁了(应该说是不可见才对?)

而如果把我所说的第一种情况改为

int i = 2000;

const int &refI = i+2; //i不是const,但refI是。

++i;

此时输出的refI的值为2002.

求问为什么会有这些差别。另外,我的第一种写法是否正确。
...全文
386 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
南京浪人甲 2011-06-09
  • 打赏
  • 举报
回复
总觉得没说明白,再举个例子:
比如你开车撞人了,警察要抓你。这时候,你如果说“我打电话给我爸,李刚!”,那么,警察就不敢抓你了。
但是如果说:“我打电话给我爸”,那么,你就被抓走了。
其实,“我爸”--非const变量
“我爸是李刚”--const变量
对别人喊的时候,就相当于--引用变量(对外) int &refI 或const int &refI
自己心里的,相当于--被引用变量(隐藏) i
1、心里想着“我爸是李刚”,喊出来“我爸”,没用,被抓走。

const int i = 2000;
int &refI = i;

2、反之,即使心里想的是“我爸”,喊出来的是“我爸是李刚”,即使你爸不是李刚,也不会被抓走。。。

int i = 2000;
const int &refI = i;


南京浪人甲 2011-06-09
  • 打赏
  • 举报
回复
就用lz的例子:

int i = 2000;
const int &refI = i; //i不是const,但refI是。
++i

1、引用就是被引用变量的别名。只要“被引用变量(i)”和“引用变量(refI)”二者其一“合法地”改变,那么另一个肯定就会变。
2、const 型引用又是一种特殊情况,如上面的例子,refI是绝对不能改变的,所以const 型引用是可以用常量进行初始化(或者是表达式)的,而非const型引用只能用相应类型的非const变量进行初始化。举几个例子:

int i = 2000;
const int &refI = i+2; //这样是可以的
++i;//这里refI绑定的是一个表达式,其与i无关,也就是i变化不能影响refI
/////////////////////////////////////////////////////////////////////
int i = 2000;
int &refI = i+2; //这样是错误的,refI不能这么初始化
++i;
/////////////////////////////////////////////////////////////////////
const int i = 2000;
int &refI = i;//这也是错误的,
/////////////////////////////////////////////////////////////////////
int &refI = 2000;错误


总结一下关键点:
1、“const型引用”可以用“非const型”进行初始化(绑定),反之不行。可以这么想,一旦使用引用,我们就好比把原来被引用的变量名(i)“隐藏”起来了,主要关注引用变量(refI),试想,如果原来的类型是const(const int i = 2000),而引用类型为非const(int &refI = i),如果这样可行,那么岂不是会有改变refI,从而非法改变i的风险;而反过来,(int i = 2000;cosnt &refI = i;)就不会有这样的风险了。
2、const型引用是很牛X的,因为他不会非法改变其被引用变量,所以被赋予了很多非const引用所没有的性质,这如楼主举得例子:

double dval = 3.14;
const int &ri = dval

南京浪人甲 2011-06-09
  • 打赏
  • 举报
回复
分都是浮云,学到东西才是最重要的啊!
囧豆粉 2011-06-09
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 shanki_pm 的回复:]
const型引用是很牛X的,因为他不会非法改变其被引用变量,所以被赋予了很多非const引用所没有的性质
[/Quote]
总结得很清楚,谢谢指教...
看样子const reference确实很强大,可以给一个对象创建一个副本(和原来的对象是同一个对象),但这个副本又没有修改这个对象的权限.只有通过其它途径修改这个对象才可以.

另外,抱歉结贴早了...没分给了...
jiangchaomr 2011-06-08
  • 打赏
  • 举报
回复
恩 临时变量的问题 学习了
囧豆粉 2011-06-08
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 supermegaboy 的回复:]
7.1.5.1 The cv-qualifiers
.............
A pointer or reference to a cv-qualified
type need not actually point or refer to
a cv-qualified object, but it is treated as
if it does; a const-qualified access path cannot be used to modify an object
even if the object referenced is a non-
const object and can be modified
through some other access path.
[/Quote]
原来是这么一回事~并不是说const就无法更改了,而是通过别的途径可以更改…
明白了~谢谢帮忙查证,也谢谢各位的耐心讲解~
飞天御剑流 2011-06-08
  • 打赏
  • 举报
回复
在C中,const的确是readonly,但在C++中,由于不再规定常量表达式必须是编译期的,因此继续把C++中的const仅仅视作readonly是不对的,此时一个const对象在表达式中就是一个常量表达式。那么const在C++中何时能视作readonly呢,当const作为类型派生的一部分时,例如楼主所举的例子,就可以视作readonly。
ryfdizuo 2011-06-08
  • 打赏
  • 举报
回复
const当初设计就是raedonly的等价。
const int& i = 4; const引用可以直接引用常量。。。
飞天御剑流 2011-06-08
  • 打赏
  • 举报
回复
在<C++ Primer>第四版中说,const Reference is a Reference To const (P.60)。
而这里有种情况:
C/C++ code
int i = 2000;
const int &refI = i; //i不是const,但refI是。
++i;
程序输出的结果,refI的值为2001.也就是说, refI的值被通过另一种途径(++i)改变了。这种写法与“const Reference is a Reference To const”的说法相悖。而且,明明是const,却被改变了,有点。。。
用的是gnu c++编译器= =。至于微软的编译器,还没有测试过。。。
这种情况书上并没有提到,既没有否认也没有肯定这种写法的正确与否。
-----------------------------------------------------------------------------------
摘录一段标准的内容给你看看,就会明白了:

7.1.5.1 The cv-qualifiers
.............
A pointer or reference to a cv-qualified type need not actually point or refer to a cv-qualified object, but it is treated as if it does; a const-qualified access path cannot be used to modify an object even if the object referenced is a non-const object and can be modified through some other access path.
guanzhouxuezi 2011-06-08
  • 打赏
  • 举报
回复
const引用可以绑定不同但相关的类型的对象或绑定到右值。
const引用表明该引用是不可改变的,如楼主的程序,如对ref1进行改变则会报错;
因为引用就是变量的别名,所以当变量改变,引用也自然就改变了。
nakedavril 2011-06-08
  • 打赏
  • 举报
回复
const 建议不要理解为常量,理解为只读
int i = 2000;
const int &refI = i;
++i;
//refI对i是只读的,只是可以通过这个别名来访问i的值,但不能修改他
至于这种写法的准确性,你下面的代码不就证明了么
int temp = dval;

const int &ri = temp;
ljt3969636 2011-06-08
  • 打赏
  • 举报
回复
第一句话是"cosnt可以引用const类型和非const类型"
ljt3969636 2011-06-08
  • 打赏
  • 举报
回复
cosnt引用const类型和非const类型,它只表示不能通过这个引用修改值,至于被引用的值是否被修改,引用就无能为力了。

另外你列举的2、3情况都是const应用可以引用中间变量造成的,而且这些中间变量都是匿名的,2你已经正确理解了

double dval = 3.14;
int &ri = dval ;//普通的非cosnt引用这样是不可以的,必须要求ri 和dval 类型一致,只有const才会产生那个中间变量,这个是const的特例!

3中refI引用到的是i+2的结果~~和i没什么关系
囧豆粉 2011-06-08
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 nakedavril 的回复:]
lz搞混了,第一种只是普通的const ref指向non const的变量,i变了,refI自然就变了和const ref指向literal 常量和其他不同的类型不是一回事
[/Quote]
呃,书上只是说A const reference can be initialized to an object of a different type or to an rvalue, such as a literal constant. 并没也提到当初值为一个对象时的具体情况,也没有说结果。倒是const reference能指向nonconst变量这点令人困惑,不是说const reference就是reference to const吗?
还是说,关于这点标准里有规定?
Ps:
我是不是钻死牛角尖了。。。

本人小白,第一次在CSDN发帖还望海涵。。。
nakedavril 2011-06-08
  • 打赏
  • 举报
回复
lz搞混了,第一种只是普通的const ref指向non const的变量,i变了,refI自然就变了和const ref指向literal 常量和其他不同的类型不是一回事

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧