左值&右值
左值肯定可以作为右值使用,但反之则不然。左值和右值的最早区别就在于能否改变。左值是可以变的,右值不能变,但是这一点在C++中已经不再成立。
在现代C++中,现在左值和右值基本上已经失去它们原本所具有的意义,对于左值表达式,通过具体名字(variant name)和引用(reference)来指定一个对象。非左值就是右值。我们来下一个定义:
左值表示程序中必须有一个特定的名字引用到这个值。
右值表示程序中没有一个特定的名字引用到这个值。
这跟它们是否可以改变,是否在栈或堆(stack or heap)中毫无关系。
右值: 包含常量,表达式,临时对象,函数返回的非引用值等等
什么是cv-qualified
c++标准里随处可见的一个单词。
a cv-qualified type is the “const”, “volatile” or “const volatile”
version of a type. that is, a variable, function, etc. declared without
one of those is cv-unqualified, while the addition of one of those
specifies a cv-qualified type.
T& 与 cont T &
普通的T&的初始式必须是一个左值
最常用的还是cont T &,因为这种类型的初始式可以不必是一个左值,甚至也不必是T类型的。比如对于
double & a = 1.0;是错误的,1.0不是左值
应当是const double & a = 1.0;相当与首先建立一个temp对象,然后将引用指向了该temp对象。
关于左值与右值的叫法实际上源自c语言
在c++中又有新的不同,在c++中某些右值是可以修改的,比如用户自定义的类(class)的构造函数生成的临时对象
Base a; Base() =a;这样也可以通过编译
但是这个右值是不能交给非const引用的,也就是说
Base& a = Base(); 是不可以的。
标准规定:
An lvalue refers to an object or function. Some rvalue expressions!athose of class or cv-qualified class type also refer to objects 。
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.
综上,实际上在Base& a = Base(); 中=可以理解成它的一个member function
另按照标准,两个继承类里虚函数的返回类型可以有小的不一致,但这个不一致是有限度的
基类里的类型应当是现在这个子类里的类型的基类 ,Sub * 和Base *是可以的,dev cpp已通过
但是int *和Base *就是不可以的了