要了解右值引用是什麼,先來看一看什麼是右值?
一般認為可以取位址的稱為左值,如果表示式的執行結果是乙個臨時變數或者物件則認為是右值,在c++11中對右值進行了嚴格的區分:分為了純右值和將亡值
純右值:如 1,2,3,a + b
將亡值:如表示式的中間結果、函式按照值的方式進行返回(臨時物件)
int g_a =10;
//函式返回值結果為引用
int&
func_a()
intmain()
右值引用和普通引用的區別:
1.普通引用型別只能引用左值,不能引用右值
2.const引用既可以引用右值也可以引用左值
3.c++11中的右值引用,只能引用右值
int
main()
通過右值引用實現移動語義:
什麼是移動語義?
移動語義:將乙個物件中的資源移動到另乙個物件中
先來看一段**
class
string
// _str:在堆記憶體,存放拼接後結果};
intmain()
strret在按照值返回時,建立了乙個臨時物件,當此臨時物件建立完成之後,strret就會被銷毀(出了函式作用域),最後使用返回的臨時物件構造s3,s3構造完成之後,臨時物件再被銷毀,可以發現,構造s3的過程中,strret和臨時物件,都是建立了然後再銷毀,相當於一共建立了三個完全相同的物件,最後只留下乙個。所以以上方式對空間來說是一種浪費行為,程式效率也會降低,所以c++11引入了移動語義
c++11中通過右值引用實現移動語義,向上述string類新增移動構造
string (string&& s)
:_str
(s._str)
strret物件的宣告週期在臨時物件建立完成之後就結束了,所以strret為將亡值,所以strret為右值,因此在strret構造臨時物件時,會採用移動構造,通過移動構造將strret中的資源轉移到臨時物件中,因為臨時物件也是右值,所以在構造s3時,也會通過移動構造去構造s3,將臨時物件中的資源移動到s3中,所以整個構造s3過程中,只需要建立一塊堆記憶體就可以了,節省空間又提公升了程式執行效率
注意:
1.移動建構函式的引數不能設定成const型別的右值引用,因為資源無法轉移而導致移動構造失敗
2.c++11中,編譯器會預設生成乙個移動構造,但是該移動構造為淺拷貝,所以當類中涉及到資
源管理時,需要自己顯式定義自己的移動構造
右值引用可以引用左值嗎?
可以,當需要右值引用去引用乙個左值時,可以使用move()函式實現,需要注意的是此函式並不具有搬移資源功能,只是將乙個左值轉換為右值,並且被轉換的左值生命週期不會因為變成了右值而改變
int
main()
左值引用與右值引用總結:
右值引用做引數和做返回值減少拷貝的本質是利用了移動構造和移動賦值
左值引用和右值引用的作用都是減少拷貝
左值引用:解決的是傳參過程中和返回值中的拷貝
//做引數
void
push
(t x)
->
void
push
(const t& x);解決的是傳參過程中減少拷貝
//做返回值
t func()
-> t&
func
() 解決的是返回值過程中的拷貝
右值引用:解決的是傳參後,,函式內部物件移動到容器空間上的問題,傳值接收返回值的拷貝
//做引數
void
push
(t&& x),解決的是push內部不再使用拷貝構造x到容器空間上而是直接構造過去
//做返回值
t func()
; 解決函式外面呼叫接收func
()返回物件的拷貝,使用移動構造,減少拷貝
C 11 中的右值引用
右值引用的功能 首先,我並不介紹什麼是右值引用,而是以乙個例子裡來介紹一下右值引用的功能 include include usingnamespacestd classobj obj constobj other vectorfoo intmain 首先我們編譯一下這個函式,執行結果如下 tianf...
C11中的右值引用
二 參考鏈結 左值是指表示式結束後依然存在的持久物件,右值是指表示式結束時就不再存在的臨時物件。看能不能對表示式取位址,如果能,則為左值,否則為右值。所有的具名變數或物件都是左值,而右值不具名。捨棄 c 語言中的左值和右值概念 乙個是純右值 prvalue,purervalue 比如,非引用返回的臨...
c 11 右值引用
右值引用 是一種復合型別,跟c 的傳統引用很類似。為更準確地區分兩種型別,我們把傳統的c 引用稱為 左值引用 而使用 引用 這一術語時,我們的意思同時包含兩種引用 左值引用和右值引用。右值引用的行為跟左值引用類似,不同之處在於 右值引用可以繫結到臨時量 右值 而 非const的 左值引用卻不能繫結到...