52.左值

  左值参数是可以被引用的数据对象。例如,变量、数组元素、结构成员、引用和接触引用的指针。非左值包括字面常量(用引号括起的字符串除外,他们由其它地址表示)和包括多项的表达式。在C语言中左值最初是可出现在赋值语句左边的实体,但这是引入关键字const之前的情况。现在,常规变量和const变量都可视为左值,因为可通过地址访问它们。但常规变量属于可修改的左值,而const修饰的变量属于不可修改的左值。

  C++的表达式要不然是右值(rvalue,读作“are-value”),要不然就是左值(lvalue,读作“ell-value”)。这两个名词是从C语言继承过来的,原本是为了帮助记忆:左值可以位于赋值语句的左侧,右值则不能。
  在C++语言中,二者的区别就没那么简单了。一个左值表达式的求值结果是一个对象或者一个函数,然而以常量对象为代表的某些左值实际上不能作为赋值语句的左侧运算对象。此外,虽然某些表达式的求值结果是对象,但它们是右值而非左值。可以做一个简单 的归纳:当一个对象被用作右值的时候,用的是对象的值(内容);当对象被用作左值的时候,用的是对象的身份(在内存中的位置)。
  不同的运算符对运算对象的要求各不相同,有的需要左值运算对象、有的需要右值运算对象:返回值也有差异,有的得到左值结果、有的得到右值结果。一个重要的原则(参见C++ Primer 13.6节,第470页将介绍一种例外的情况)是在需要右值的地方可以用左值来代替,但是不能把右值当成左值(也就是位置)使用。 当一个左值被当成右值使用时,实际使用的 是它的内容(值)。到目前为止,已经有几种我们熟悉的运算符是要用到左值的。

●赋值运算符需要一个(非常量)左值作为其左侧运算对象,得到的结果也仍然是一个左值。
●取地址符(参见C++ Primer 2.3.2节,第47页)作用于一个左值运算对象,返回一个指向该运算对象的指针,这个指针是一个右值。
●内置解引用运算符、下标运算符(参见C++ Primer 2.3.2节, 第48页:参见C++ Primer 3.5.2节,第104 页)、迭代器解引用运算符、String和vector的下标运算符(参见C++ Primer 3.4.1节,第95页;参见C++ Primer 3.2.3节,第83页;参见C++ Primer 3.3.3节,第91页)的求值结果都是左值。
●内置类型和迭代器的递增递减运算符(参见C++ Primer 1.4.1节,第11页;参见3.4.1节,第 96 页)作用于左值运算对象,其前置版本(本书之前添节所用的形式)所得的结 果也是左值。

  使用关键字decltype(参见2.5.3节, 第62页)的时候,左值和右值也有所不同。如果表达式的求值结果是左值,decltype 作用于该表达式(不是变量)得到一个引用类型。举个例子,假定p的类型是int *,因为解引用运算符生成左值,所以decltype (*p) 的结果是int&。 另一方面,因为取地址运算符生成右值,所以decltype(&p)的结果是int**,也就是说, 结果是一个指向整型指针的指针。

参考资料

参考资料来源于黑马程序员,C++ Primer

posted @ 2023-02-23 22:34  CodeMagicianT  阅读(45)  评论(0编辑  收藏  举报