什麼是對象?
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