1. 程式人生 > >深入解讀C++中的右值引用

深入解讀C++中的右值引用

右值引用(及其支援的Move語意和完美轉發)是C++0x將要加入的最重大語言特性之一,這點從該特性的提案在C++ - State of the Evolution列表上高居榜首也可以看得出來。
從實踐角度講,它能夠完美解決C++中長久以來為人所詬病的臨時物件效率問題。從語言本身講,它健全了C++中的引用型別在左值右值方面的缺陷。從庫設計者的角度講,它給庫設計者又帶來了一把利器。從庫使用者的角度講,不動一兵一卒便可以獲得“免費的”效率提升…
在標準C++語言中,臨時量(術語為右值,因其出現在賦值表示式的右邊)可以被傳給函式,但只能被接受為const &型別。這樣函式便無法區分傳給const &的是真實的右值還是常規變數。而且,由於型別為const &,函式也無法改變所傳物件的值。C++0x將增加一種名為右值引用的新的引用型別,記作typename &&。這種型別可以被接受為非const值,從而允許改變其值。這種改變將允許某些物件建立轉移語義。比如,一個std::vector,就其內部實現而言,是一個C式陣列的封裝。如果需要建立vector臨時量或者從函式中返回vector,那就只能通過建立一個新的vector並拷貝所有存於右值中的資料來儲存資料。之後這個臨時的vector則會被銷燬,同時刪除其包含的資料。有了右值引用,一個引數為指向某個vector的右值引用的std::vector的轉移構造器就能夠簡單地將該右值中C式陣列的指標複製到新的vector,然後將該右值清空。這裡沒有陣列拷貝,並且銷燬被清空的右值也不會銷燬儲存資料的記憶體。返回vector的函式現在只需要返回一個std::vector<>&&。如果vector沒有轉移構造器,那麼結果會像以前一樣:用std::vector<> &引數呼叫它的拷貝構造器。如果vector確實具有轉移構造器,那麼轉移構造器就會被呼叫,從而避免大量的記憶體分配。

一. 定義
通常意義上,在C++中,可取地址,有名字的即為左值。不可取地址,沒有名字的為右值。右值主要包括字面量,函式返回的臨時變數值,表示式臨時值等。右值引用即為對右值進行引用的型別,在C++98中的引用稱為左值引用。
如有以下類和函式:

?
1 2 3 4 5 6 7 8 9 10 class A { private: int* _p; }; A ReturnValue() { return A(); }
ReturnValue()的返回值即為右值,它是一個不具名的臨時變數。在C++98中,只有常量左值引用才能引用這個值。 ?
1 2 3 A& a = ReturnValue(); // error: non-const lvalue reference to type 'A' cannot bind to a temporary of type 'A' const A& a2 = ReturnValue(); // ok
通過常量左值引用,可以延長ReturnValue()返回值的生命週期,但是不能修改它。C++11的右值引用出場了:
?
1 A&& a3 = ReturnValue();
右值引用通過”&&”來宣告, a3引用了ReturnValue()的返回值,延長了它的生命週期,並且可以對該臨時值進行修改。

二. 移動語義
右值引用可以引用並修改右值,但是通常情況下,修改一個臨時值是沒有意義的。然而在對臨時值進行拷貝時,我們可以通過右值引用來將臨時值內部的資源移為己用,從而避免了資源的拷貝:

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14

相關推薦

深入解讀C++中的右引用

右值引用(及其支援的Move語意和完美轉發)是C++0x將要加入的最重大語言特性之一,這點從該特性的提案在C++ - State of the Evolution列表上高居榜首也可以看得出來。 從實踐角度講,它能夠完美解決C++中長久以來為人所詬病的臨時物件效率問題

C++ 右引用與移動操作

銷毀 帶來 臨時對象 類型 左值引用 都是 獲得 留下 c++11 右值引用和移動操作是C++11提出的新概念,通過這些操作,可以降低拷貝操作帶來的消耗。先來簡單介紹一下左值和右值。 左值一般指的是一個對象,或者說是一個持久的值,例如賦值的返回值、下標操作、解引用以及前置遞

C++左引用和右引用

分配內存 右值 markdown type 提高 指向 區分 基本語法 down 1.左值和右值概念: 左值是可以放在賦值號左邊可以被賦值的值:左值就是指在表達式使用完之後仍存在的對象(存儲空間); 右值當在賦值號右邊去除值賦給其他變量的值:右值可以在內存也可以在CPU寄存

c++右引用以及使用

什麽 函數的參數 .html 顯式 pan 但是 cout 表達式 信息 前幾天看了一篇文章《4行代碼看看右值引用》 覺得寫得不錯,但是覺得右值引用的內容還有很多可以去挖掘學習,所以總結了一下,希望能對右值引用有一個更加深層次的認識 一、幾個基本概念 1.1左值和右值 左值

c++ 右引用,move關鍵字

賦值函數 .cpp 一次 -s 編譯器 一份 簡單 som this c++ move關鍵字 move的由來:在 c++11 以前存在一個有趣的現象:T& 指向 lvalue (左傳引用), const T& 既可以指向 lvalue 也可以指向 rval

【轉載】c++右引用以及使用

轉自:https://www.cnblogs.com/likaiming/p/9045642.html 前幾天看了一篇文章《4行程式碼看看右值引用》 覺得寫得不錯,但是覺得右值引用的內容還有很多可以去挖掘學習,所以總結了一下,希望能對右值引用有一個更加深層次的認識 一、幾個基本概念 1.

喵喵喵?喵嘞個咪?---- C++左引用

編譯環境:VS 2013 一、C 語言傳參 1. 傳值 void swap(int left, int right) { int temp = left; left = right; right = temp; } 這個函式很簡單,就是一個交換兩數

【強文翻譯】c++右引用詳解

原文連結譯註:這篇是我讀過有關右值引用的文章中最通俗易懂的一篇,易懂的同時,其內容也非常全面,所以就翻譯了一下以便加深理解。有翻譯不準的地方請留言指出。INTRODUCTION右值引用是C++11標準中引入的新特性,由於右值引用所解決的問題並不是很直觀,所以很難在一開始就很好

[C++] 右引用:移動語義與完美轉發

C++11 引入的新特性中,除了併發記憶體模型和相關設施,這些高帥富之外,最引人入勝且接地氣的特性就要屬『右值引用』了(rvalue reference)。加入右值引用的動機在於效率:減少不必要的資源拷貝。考慮下面的程式: std::vector<string>

深入探討C++中的引用

 摘要:介紹C++引用的基本概念,通過詳細的應用分析與說明,對引用進行全面、透徹地闡述。   關鍵詞:引用,const,多型,指標   引用是C++引入的新語言特性,是C++常用的一個重要內容之一,正確、靈活地使用引用,可以使程式簡潔、高效。我在工作中發現,許多人使用它僅僅

C++ 右引用

右值引用用於獲取匿名變數的使用權,並延長匿名變數的生命週期,比如表示式的返回和函式的返回,都是由編譯器建立的一些變數,沒有右值引用的時候只能通過賦值給 中間變數的方法來保持住這個值,但是這也增加了一次構造的開銷。為了能夠保持這個值而且又不用去再次構造那麼就可以用右值引用。除

C++——左引用和右引用

   這篇blog主要介紹一下左值和右值的概念及應用陷阱 1、左值和右值的概念          左值是可以放在賦值號左邊可以被賦值的值;左值必須要在記憶體中有實體;          右值當在賦值號

C++右引用和移動語義淺說

1、神馬叫右值和右值引用C++中所有的值分兩種,一種叫左值(可以取地址,有名字的),一種叫右值(不可以取地址,沒有名字的)。常見的如 int a  = b+c ;表示式中a  可以取地址為左值,(b+c

C++右引用

說明     為了支援移動操作,新標準引入了一種新的引用型別——右值引用(rvalue refe

C++左引用與右引用

本文翻譯自:https://docs.microsoft.com/en-us/cpp/cpp/references-cpp?view=vs-2019   引用,類似於指標,用於儲存一個位於記憶體某處的物件的地址。與指標不同的是,引用在被初始化後不能再指向另一個物件,或設定為null。引用分為兩種:左值引用,右

一段小程式碼秒懂C++右引用和RVO(返回優化)的誤區

關於C++右值引用的[參考文件](https://en.cppreference.com/w/cpp/language/reference)裡面有明確提到,右值引用可以延長臨時變數的週期。如: ```C std::string&& r3 = s1 + s1; // okay: rvalue r

深入理解C++11》筆記–右引用:移動語義和完美轉發

上一篇:《深入理解C++11》筆記–建構函式 這篇文章介紹的了第三章中右值引用相關的內容。在介紹該內容之前,會對一些相關問題進行解釋,便於理解後面的內容。 並且,提前說明,許多編譯器會多拷貝構造和移動構造進行優化省略,這樣就看不到拷貝構造和移動構造的過程,需

C++11:深入理解右引用,move語義和完美轉發

深入右值引用,move語義和完美轉發 轉載請註明:http://blog.csdn.net/booirror/article/details/45057689 乍看起來,move語義使得你可以用廉價的move賦值替代昂貴的copy賦值,完美轉發使得你可以將傳來的任意

C#基礎知識-引用類型和類型的區別(六)

值類型 type 調用 執行 new 內存堆 ada ont 不同類 在第一篇中我們介紹了C#中基本的15種數據類型,這15種數據類型中又分為兩大類,一種是值類型,一種是引用類型。值類型有sbyte、short、long、int、byte、ushort、uint、u

C++11的右引用

右值引用 語法 factor htm 類型 har start 移動 hand 右值引用是C++11 引入的新特性。它解決了兩類問題:實現移動語義和完美轉發。本文大絕大部分內容,來自於文章:http://kuring.me/post/cpp