右值引用(rvalue reference),是C++11标准提出的一类数据类型。用于实现移动语义(move semantic)与完美转发(perfect forwarding)。但是对于右值引用的理解,自己常常把握不好,现将目前阶段的理解记录下来。有不对的地方欢迎指正。
关于“右值引用”的定义,c++ PRimer(第五版,下同)给了一句废话。。。
所谓右值引用就是必须绑定到右值的引用
然后所谓右值’返回非引用类型的函数,连同算术、下标、解引用和前置递增/递减运算符,都生成右值’ 也就是书里所说的将要销毁的对象 个人理解为没有具体变量名的值,一般在一句代码分号结束后就销毁。例如:
int i = 0;i+1;// 这个就是一个右值。它的值为1,但是没有具体的变量名称,这句代码结束后就被销毁。虽然c++ primer没有给出非常明确的定义,但是说了很多右值的属性和属性便于我们理解 毕竟右值这东西也不是三言两语就能说明白的嘛
右值只能绑定到一个将要销毁的对象。因此,我们可以自由地将一个右值引用的资源”移动”到另一个对象中。
因为右值即将销毁,但是我们定义一个右值引用后,就可以通过这个右值引用访问和修改这个右值,相当于使 这个即将销毁的右值“起死回生”,延长了其生命周期:
struct A{ A(){ cout << "A() "<<endl; } ~A(){ cout << "~A()" << endl; } int i = 0;};int main(int argc, char *argv[]){ // 此处注释打开前,A的析构输出会在"end main func"这句之前 /*A&& rA =*/ A(); cout<< "end main func" <<endl; return 0;}类似任何引用,一个右值引用也不过是某个对象的另一个名字而已。
是的,右值引用是一个别名,但是下面这个就不好理解了:
int &&rr1 = 42; // 正确: 字面值常量是右值int &&rr2 = rr1; // 错误:表达式rr1是左值!c++ primer对此的解释是:rr1变量名看做是一个没有运算符号的表达式
, 变量表达式都是左值
!!!
最后就很好理解下面这些例子了:
int i = 42;int &r = i; // 正确: r引用iint &&rr = i; // 错误: i是变量,变量表达式是左值int &r2 = i * 42; // 错误:i*42是一个右值const int &r3 = i * 42; // 正确:const引用可以绑定到一个右值上int &&rr2 = i * 42; // 正确:右值引用int &&rr3 = r3; // 错误:r3是变量,变量表达式是左值const引用和右值引用都可以引用右值,但是const引用只有读权限,右值引用对可以右值有读写(“窃取”资源)权限 一般定义右值引用都是为了修改被引用对象的资源,移动到新的新的对象上去,从而避免浪费,因为右值都是将要被销毁的值
。 所以常量右值引用const X&&
较少用到。
新闻热点
疑难解答