C++11新特性(1) 右值引用
在C++中,左值(lvalue)是能够获取其地址的一个量。因为常常出如今赋值语句的左边。因此称之为左值。比如一个有名称的变量。
比如:
int a=10; //a就是一个左值。
传统的C++引用,都是左值引用。比如:int &ra=a;将ra关联到a。这就是左值引用。
C++11,新增了右值引用的概念。
用&&代表右值引用。
首先我们来看一下什么叫做右值。
能够说全部不是左值的量都是右值。比如文本,暂时对象或者暂时值(都是不能获取地址的量)。
右值引用。就是一个对右值的引用。特别地,这是一个当右值是一个暂时对象时使用的概念。
比如。
int &&ra=10;
10就是一个右值。ra将是10这个右值的引用。看样例:
#include <iostream> using namespace std; int main() { int &&ra=9; cout<<&ra<<endl<<ra<<endl; ra=5; cout<<&ra<<endl<<ra<<endl; cin.get(); }输出结果:
有趣的是,将右值关联到右值引用将导致该右值被存储到特定的位置,且能够获取该位置的地址。
比如。你不能对右值9或者5进行&运算。可是能够对ra进行&运算。
右值引用的目的是提供一些涉及暂时对象时能够选用特定的方法(主要是复制构造函数以及operator=,但并不限于此)。因为知道暂时对象会被销毁。通过右值引用,某些涉及复制大量数据的操作能够通过简单地复制指向这些值的指针来实现。
方法能够将&&作为參数说明的一部分,从而指定右值引用參数。看样例:
#include <iostream> using namespace std; void showMax(int &a,int &b){ if(a>b) cout<<a<<endl; else cout<<b<<endl; } int main() { int a=10; int b=5; showMax(a,b); //showMax(20,15); // invalid initialization of non-const reference of type 'int&' from an rvalue of type 'int'| cin.get(); return 0; }发现showMax(20,15)的时候无法正常编译。
这是由于20,15是一个右值。以下我们定义一个右值引用版本号的showMax();
#include <iostream> using namespace std; void showMax(int &a,int &b){ if(a>b) cout<<a<<endl; else cout<<b<<endl; }; void showMax(int &&a,int &&b){ cout<<"这是一个右值引用比較"<<endl; if(a>b) cout<<a<<endl; else cout<<b<<endl; } int main() { int a=10; int b=5; showMax(a,b); showMax(20,15); return 0; }
执行结果:
当调用showMax(20,15)的时候,编译器将自己主动调用相相应的右值引用的版本号。
作为方法的參数的时候右值引用很实用。又比如:
#include <iostream> using namespace std; void show(int &a){ cout<<"左值引用:"<<a<<endl; }; void show(int &&a){ cout<<"这是一个右值引用:"<<a<<endl; } int main() { int a=10; int b=5; show(a); show(a+b); show(a++); //右值引用 show(++a); //左值引用 show(b+100); show(100+200); }
结果:
须要注意的是:
show(a++); //右值引用
show(++a); //左值引用
a++是先取出持久对象a的一份拷贝,再使持久对象a的值加1,最后返回那份拷贝,而那份拷贝是暂时对象(不能够对其取地址),故其是右值;
++a则是使持久对象a的值加1,并返回那个持久对象a本身(能够对其取地址),故其是左值。
右值引用单独使用的情况非常少。一般都是用于作为方法的參数或者函数的參数。使用的最多的情况则是用在移动语义之上。