C++中关于左值和右值的讨论
要求是左值数组,上述表达式合法。另外,在这里f()虽然是右值,但是f()却引用到一个对象,我们通过f()。c[0]左值表达式可以引用到该对象的一部分,并且通过(*)可以修改它(因为该左值表达式是modifiable lvalue,但是尝试修改它的行为是未定义的,然而从左右值性上是行得通的 )
* 关于数组类型 数组类型在大部分场合都会退化为一个指向其首元素的指针(右值),因而在左右值性和类型判断上,容易发生误解。数组不发生退化的地方有几个场合,一是声明时;一是用作sizeof的操作数时;一是用作&取址运算的操作数时。
C++中,数组还有其他场合不发生退化,比如作为引用的initializer;作为typeid/ typeinfo的操作数和模板推导时。 2 C++的左值 2.1 与C不同的是,C++中,一个左值表达式,不仅可以引用到对象,同样也可以引用到一个函数上。假定f是一个函数名,那么表达式f就表示一个左值表达式,该表达式引用到对应的函数;void (*p)(void); 那么*p也是一个左值。然而一个函数类型的左值是不可修改的。 *p=f;// error. (注:类的non-static member function,不是这里指的函数类型,它不能脱离对象而存在; 而static member function是函数类型) 另一个不同之处在于,对于register变量,C++允许对其取址,即register int i; &i;这种取址运算,事实上要求C++编译器忽略掉register specifier指定的建议。无论在C/C++中, register与inline一样都只是对编译器优化的一个建议,这种建议的取舍则由编译器决定。 C++中,一个右值的class type表达式,引用到一个对象;这个对象往往是一个临时对象(temporary object)。在C++中,我们可以通过class type的右值表达式的成员函数来间接修改对象。
需要再次说明的是,C++中的class type的右值表达式可以具有const/volatile属性,而在C中右值总是cv-unqualified.
在C中,f()的返回值总是一个右值表达式,具有struct A类型(const被忽略)。 2.2 C++中引入了引用类型(reference type),引用总是引用到某一对象或者函数上,因此当我们使用引用时,相当于对其引用的对象/函数进行操作,因而引用类型的表达式总是左值。 (在分析表达式类型时,如果一个表达式expr最初具有T&类型,该表达式会被看作具有类型T的左值表达式)
函数调用f()的返回类型为int&, 因此表达式f()的类型等价于一个int类型的左值表达式。 而函数调用g()的返回类型为int,因此表达式g()为int类型的右值表达式。 与C++相比,C中函数调用的返回值总是右值的。 2.3 与C相比,在C++中,转换表达式可能产生左值。如果转换的目标类型为引用类型T&,转换表达式的结果就 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |