什么是对象?
An object is "something in memory".express
什么是左值,什么是右值?
An lvalue expression identifies a non-temporary object.
An rvalue expression identifies a temporary object or a value associated with no object.
As a general rule, if you have a name for a variable, it is an lvalue.
An l-value expression refers to an object's identity, whereas a r-value expression refers to an object's value.
左值标识对象的身份,右值标识对象的值。ide
常见的左值有“变量名”,常见的右值有“字面量”或者“变量经std::move转换的结果”。函数
引用:A reference allows us to define a new name for an existing value. 既然是新名,而不是新对象,那么不管是左值仍是右值引用,它们的做用都是避免拷贝,典型应用场景有传参和返回值,range for loops。二者的区别在于,右值引用所绑定对象是被原主人抛弃了的,容许被偷走。而左值引用不能够。oop
C++11增长了对右值引用的支持,右值引用是干什么的呢?指针
从字面意思理解,右值引用固然是用来标识一个右值的身份了,经过它能够找到绑定的右值,方便对右值的读写。code
在没有右值引用以前,没有办法用变量标识一个右值,右值只可能短暂地存在,不可能被二次访问。更不要说跨函数地传递了(传参和返回值)。有了右值引用类型以后,这一切将变成可能。对象
std::move函数的做用是把一个左值转变成右值返回。ci
若是返回的右值被用做了move操做(move constructor / assignment)的参数,那么原来的左值x所占有的资源已经被别的对象偷走,后面再对x操做时要明白,x的一部分资源已经不可靠了。资源
若是x是stl定义的类型,stl向咱们保证x的赋值和析构操做是能够正常执行的,string
若是x是咱们自定义的类型,应该注意,move constructor / assignment操做应该保证跳出函数后x能够正常被析构。
谁和谁能够绑定到一块儿?
int i = 10; // 右值引用-右值 int&& rr = 42; int&& rr1 = std::move(i); //const左值引用--右值 const int& c = 42; //左值引用--左值 int& lr = rr; //注意:右值引用也是变量,因此rr是左值。
右值引用常见用法
1.若是把左值引用理解为变量的别名,那么右值引用就是资源的别名。经过右值引用能够直接操做藏在对象名后面的对象资源。
string a = "aaa"; string&& r = std::move(a); r = "rrr"; cout << a << endl; /*output: rrr */
2.做为move constructor 和 move assignment的参数。
string a("aaa"); string b(std::move(a)); cout << "move construct b from a, a:" << a << "\tb:" << b << endl; string c("ccc"); c = std::move(b); cout << "move assignment c from b, b:" << b << "\tc:" << c << endl;//可见,string的拷贝赋值里,对b和c的资源指针作了swap