免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: thinshootout
打印 上一主题 下一主题

[C++] 关于C++中的临时变量的讨论 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2007-10-03 12:06 |只看该作者
f5() = X(1)中,f5()应该不是右值,就是一个临时对象,在f5()未返回的时候对caller来说是右值,但这里f5()已经返回到caller,caller生成了一个临时对象,=X(1)是改变该临时对象的值。

个人理解c++规定临时对象只能赋给const引用是为了在编译时发现一些逻辑上的错误,具体见http://bbs.chinaunix.net/viewthread.php?tid=993395

论坛徽章:
0
12 [报告]
发表于 2007-10-03 15:54 |只看该作者

回复 #11 tianqio 的帖子

这里好像存在了“右值”和“临时对象”概念上的模糊不清。请问临时对象一定是右值吗?按照C++ primer上所说,右值是不会改变的,但依 whyglinux 兄所说,函数返回值必定是右值,而如果该右值又是类对象的话,又是可以改变的。似乎有点矛盾。
还请各位大虾不吝赐教。

论坛徽章:
0
13 [报告]
发表于 2007-10-05 16:27 |只看该作者
收藏了

论坛徽章:
0
14 [报告]
发表于 2007-10-06 10:47 |只看该作者
>> 临时对象:对于某对象,如果未被通过定义变量来显式分配地址,而是由编译器临时分配内存空间,并负责释放内存空间,则该对象即为“临时对象”。
>> ----------------------------------------------------------------------------
对象的生成方式可以有以下 4 种:
  • 通过定义产生。这样的对象是自动对象或者静态对象。
  • 通过动态内存分配产生。这样的对象是动态对象。
  • 使用字符串字面量。字符串字面量是一个静态对象。
  • 上面三种方式是用户(程序员)在程序中生成对象的方式。除此之外,编译器也可根据需要生成对象,这样的对象即为临时对象。

>> 常量:通过const关键字修饰的(应与“文字量”相区别),表示不会变化的值。
>> ----------------------------------------------------------------------------
通过 const 关键字修饰的其实是对象,这样的对象称为“常量对象”。而我们所说的“常量(Constant)”通常指的是“字面量(Literal)”,一般不是对象(字符串字面量除外)。

>> 左值也可以是引用了某个常量。
>> ----------------------------------------------------------------------------

???

>> 没有被声明为常量的左值常被称为“可修改的左值”(可寻址)。
>> ----------------------------------------------------------------------------
“没有被声明为常量的左值”应该是“没有 const 限制(或修饰)的左值”为好。另外,const 限制的左值对象固然不能修改,有时没有 const 限制的对象也是不能被修改的,比如数组对象。可修改以及不可修改的左值都是可寻址的。

>> 右值:变量的数据值,存储在某个内存地址中(摘自C++ Primer)。
>> ----------------------------------------------------------------------------
上面说的是变量作为右值使用的情况(lvalue-to-rvalue变换)。需要注意的是,右值可能来自于内存中的某一对象,也可能跟内存中的对象毫无关系。

>> 临时对象与常量:除非是一个 const 类型的临时对象,否则不是常量。
>> ----------------------------------------------------------------------------
临时对象与常量:除非是一个 const 类型的临时对象,否则不是常量 对象

要区分“常量”、“常量对象”、“常量表达式”等概念。

>> 右值只是一个表达式,它表示了一个值或一个引用了临时对象的表达式,用户不能寻址该对象,也不能改变它的值
>> 这句话是从C++ Primer上原封不动摘下来的
>> ----------------------------------------------------------------------------
C++ 中出现了“可修改的右值”这样的概念,当然仅仅适用于类对象,对于非类对象保持和 C 的兼容。C++ Primer 上的这句话是不准确的。另外,C++ Primer 上面还有一些论断不符合实际情况,需要注意。例如在“3.1 文字常量”一节中有这么一句话:

“文字常量是不可寻址的nonaddressable 尽管它的值也存储在机器内存的某个地方但是我们没有办法访问它们的地址。”

然而,字符串字面量是它所说的文字常量,它是可寻址的。另外,在上面也已经说过了,作为右值的文字常量可能在内存中根本就不存在。

论坛徽章:
0
15 [报告]
发表于 2007-10-06 10:49 |只看该作者
原帖由 tianqio 于 2007-10-3 12:06 发表
f5() = X(1)中,f5()应该不是右值,就是一个临时对象,在f5()未返回的时候对caller来说是右值,但这里f5()已经返回到caller,caller生成了一个临时对象,=X(1)是改变该临时对象的值。


在 C++ 中,一个表达式不是左值就是右值,没有第三种情况存在。那么,f5() 是左值吗?

论坛徽章:
0
16 [报告]
发表于 2007-10-06 18:56 |只看该作者
函数的返回值会依据返回数据的大小返回在不同的地方,一般来说整数是通过寄存器来返回,这种情况下函数返回值是右值,而如果返回的是一个对象,则是通过内存传递的,在这种情况下,在caller中用来存放返回值的这个对象就是一个临时对象,是一个左值,可以被修改。

个人理解,欢迎讨论。

论坛徽章:
0
17 [报告]
发表于 2007-10-06 22:00 |只看该作者
原帖由 tianqio 于 2007-10-6 18:56 发表
函数的返回值会依据返回数据的大小返回在不同的地方,一般来说整数是通过寄存器来返回,这种情况下函数返回值是右值,而如果返回的是一个对象,则是通过内存传递的,在这种情况下,在caller中用来存放返回值的这 ...


C++ 标准 3.10 Lvalues and rvalues 第 5 段规定:

The result of calling a function that does not return a reference is an rvalue.

关于存在可变的 rvalue 是在第 10 段叙述的:

An lvalue for an object is necessary in order to modify the object except that an rvalue of class type can also be used to modify its referent under certain circumstances. [ Example: a member function called for an object (9.3) can modify the object. —end example ]

论坛徽章:
0
18 [报告]
发表于 2007-10-26 16:11 |只看该作者
奇怪了,这个帖子怎么沉了了?
左值,右值
表达式左边,表达式右边

很有趣的话题啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP