亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

詳解C++11中的右值引用與移動語義

2020-01-26 14:15:21
字體:
來源:轉載
供稿:網友

C++11的一個最主要的特性就是可以移動而非拷貝對象的能力。很多情況都會發生對象的拷貝,有時對象拷貝后就立即銷毀,在這些情況下,移動而非拷貝對象會大幅度提升性能。

右值與右值引用

為了支持移動操作,新標準引入了一種新的引用類型――右值引用,就是必須綁定到右值的引用。我們通過&&而不是&來獲得右值引用。右值引用一個重要的特性就是只能綁定到將要銷毀的對象。

左值和右值是表達式的屬性,一些表達式生成或要求左值,而另一些則生成或要求右值。一般而言,一個左值表達式表示的是一個對象的身份,而右值表達式表示的是對象的值。(可以取地址的、有名字的就是左值;不能取地址的、沒有名字的就是右值。)兩者明顯的區別就是左值有持久的狀態,而右值要么是字面常量,要么是在表達式求值過程中創建的臨時對象。

類似于常規引用(左值引用),一個右值引用也不過是某個對象的另一個名字而已。我們不能將左值引用綁定到要求轉換的表達式、字面常量或是返回值的表達式,也不能把右值應用直接綁定到一個左值上。但是,常量左值引用可以綁定到非常量左值、常量左值、右值,是一個萬能引用類型。不過相比右值引用所引用的右值,常量左值引用所引用的右值在它的“余生”中只能是只讀的。

int i = 42;int &r = i;     //r引用iint &r2 = i*2;    //錯誤,i*2是一個右值int &&rr = i;    //錯誤,不能將一個右值引用綁定到一個左值上int &&rr2 = i*2;   //正確,將rr2綁定到一個乘法結果上const int &r3 = i*2; //正確,將一個常量引用綁定到一個右值上

變量可以看做只有一個運算對象而沒有運算符的表達式,是一個左值。我們不能將一個右值引用直接綁定到一個變量上,即使這個變量是右值引用類型。但是,我們可以通過新標準庫中的move函數來獲得綁定到左值上的右值引用。

int &&rr3 = std::move(rr2);

注意,被轉化的左值,其生命周期并沒有隨著左右至的轉化而改變,在轉換之后使用左值可能造成運行時錯誤。因此,調用move就意味著承諾:除了對原左值變量賦值或銷毀它外,我們將不再使用它。不過更多的時候,我們需要轉換成右值引用的還是一個確實生命周期即將結束的對象。

移動構造函數和移動賦值運算符

為了讓自定義類型也支持移動操作,需要為其定義移動構造函數和移動賦值運算符。這兩個成員類似對應的拷貝操作,但它們從給定對象竊取資源而不是拷貝資源。類似于拷貝構造函數,移動構造函數的第一個參數是該類類型的一個右值引用,任何額外的參數都必須有默認實參。除了完成資源移動外,移動構造函數還必須確保移后源對象處于有效的、可析構的狀態。

#include <iostream> #include <algorithm> class MemoryBlock { public:   // 構造函數  explicit MemoryBlock(size_t length) : _length(length) , _data(new int[length]) {}   // 析構函數   ~MemoryBlock()   {    if (_data != nullptr)  delete[] _data;  }   // 拷貝賦值運算符   MemoryBlock& operator=(const MemoryBlock& other)   {     if (this != &other)     {       delete[] _data;       _length = other._length;       _data = new int[_length];       std::copy(other._data, other._data + _length, _data);     }     return *this;   }   // 拷貝構造函數   MemoryBlock(const MemoryBlock& other)     : _length(0)     , _data(nullptr)   {     *this = other;   }   // 移動賦值運算符,通知標準庫該構造函數不拋出任何異常(如果拋出異常會怎么樣?)  MemoryBlock& operator=(MemoryBlock&& other) noexcept  {    if (this != &other)     {        delete[] _data;       // 移動資源      _data = other._data;       _length = other._length;       // 使移后源對象處于可銷毀狀態      other._data = nullptr;       other._length = 0;     }     return *this;   }  // 移動構造函數  MemoryBlock(MemoryBlock&& other) noexcept    _data(nullptr)     , _length(0)   {     *this = std::move(other);   }   size_t Length() const   {     return _length;   } private:   size_t _length; // The length of the resource.   int* _data; // The resource. };

只有當一個類沒有定義任何自己版本的拷貝控制成員,且類的每個非static數據成員都可移動時,編譯器才會為它合成移動構造函數會移動賦值運算符。編譯器可以移動內置類型;如果一個類類型有對應的移動操作,編譯器也能移動這個類型的成員。此外,定義了一個移動構造函數或移動賦值運算符的類必須也定義自己的拷貝操作;否則,這些成員默認地定義為刪除的。而移動操作則不同,它永遠不會隱式定義為刪除的。但如果我們顯式地要求編譯器生成=defualt的移動操作,且編譯器不能移動所有成員,則編譯器會將移動操作定義為刪除的函數。

如果一個類既有移動構造函數又有拷貝構造函數,編譯會使用普通的函數匹配規則來確定使用哪個構造函數。但如果只定義了拷貝操作而未定義移動操作,編譯器不會合成移動構造函數,此時即使調用move來移動它們,也是調用的拷貝操作。

class Foo{public:  Foo() = default;  Foo(const Foo&);  // 為定義移動構造函數};Foo x;Foo y(x);         //調用拷貝構造函數Foo z(std::move(x));   //調用拷貝構造函數,因為未定義移動構造函數

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美日韩中国免费专区在线看| 欧美成人精品h版在线观看| 欧美激情网友自拍| 伊人亚洲福利一区二区三区| 国产精品久久久久久久久久| 国产97色在线|日韩| 日韩欧美国产网站| 98精品国产高清在线xxxx天堂| 久久久久久91香蕉国产| 亚洲aa中文字幕| 日韩av在线免费| 日韩高清电影免费观看完整版| 欧美日韩精品在线视频| 欧美日韩第一视频| 色老头一区二区三区| 久久久久久av| 欧美理论片在线观看| 国产精品激情av电影在线观看| 国产精品人成电影在线观看| 欧美在线视频免费播放| 亚洲国产91精品在线观看| 狠狠操狠狠色综合网| 日本精品va在线观看| 青青久久aⅴ北条麻妃| 一区二区欧美激情| 国产精品香蕉av| 在线观看免费高清视频97| 亚洲视频自拍偷拍| 国产91精品视频在线观看| 欧美电影免费观看高清完整| 久久69精品久久久久久国产越南| 国产精品视频最多的网站| 欧美成人国产va精品日本一级| 91久久精品国产91久久性色| 欧美激情xxxxx| 亚洲国产欧美自拍| 国产综合香蕉五月婷在线| 久久久www成人免费精品张筱雨| 成人美女免费网站视频| 国产精品日韩在线观看| 亚洲激情在线视频| 欧美极品少妇与黑人| 欧美黑人性视频| 国产成人精品亚洲精品| 欧美在线性爱视频| 日韩电视剧在线观看免费网站| 亚洲自拍欧美色图| 欧美疯狂性受xxxxx另类| 国产精品免费视频久久久| 欧美二区在线播放| 国产欧美一区二区三区久久| 亚洲福利视频久久| www日韩欧美| 久久精品视频网站| 日韩av快播网址| 国产日韩精品在线| 久久伊人色综合| 日韩成人在线视频| 91免费观看网站| 日韩美女免费线视频| 国产欧美中文字幕| 日韩在线观看高清| 国产精品∨欧美精品v日韩精品| 国产成人亚洲综合91精品| 不卡伊人av在线播放| 欧美性受xxxx白人性爽| 国产精品激情av在线播放| 国产一区二区成人| 啊v视频在线一区二区三区| 国产精品va在线播放| 亚洲片在线观看| 久久久精品电影| 国内精品视频久久| 日韩免费电影在线观看| 日韩电影中文字幕在线观看| 亚洲欧洲第一视频| 亚洲第一页自拍| 91九色国产社区在线观看| 日韩大陆毛片av| 国产精品久久不能| 亚洲男人天天操| 国产91九色视频| 欧美日韩国产一中文字不卡| 精品中文视频在线| 欧美第一黄色网| 精品视频在线播放色网色视频| 日本一本a高清免费不卡| 国产精品第2页| 成人在线观看视频网站| 国产亚洲欧美日韩美女| 插插插亚洲综合网| 亚洲人在线视频| 亚洲人成77777在线观看网| 亚洲精品影视在线观看| 欧美一级大片视频| 51视频国产精品一区二区| 91久久国产综合久久91精品网站| 一本大道香蕉久在线播放29| 欧美激情在线观看| 国产欧美久久久久久| 日韩精品免费在线视频观看| 久久久久久久久久久免费| 成人福利在线视频| 精品少妇v888av| 69影院欧美专区视频| 久久精品国产清自在天天线| 国产成人一区二区| 精品国产1区2区| 中文字幕亚洲一区二区三区五十路| 91av国产在线| 久久久久久网址| 中文字幕亚洲欧美日韩高清| 97视频免费在线观看| 久久激情视频免费观看| 2018国产精品视频| 日韩激情在线视频| 日韩在线观看高清| 国产精品亚洲综合天堂夜夜| 亚洲国产一区二区三区四区| 国产+人+亚洲| 欧美伊久线香蕉线新在线| 中文字幕自拍vr一区二区三区| 九九热这里只有精品6| 日韩精品亚洲精品| 国产ts一区二区| 久久久久久久久久婷婷| 久久亚洲精品小早川怜子66| 欧美重口另类videos人妖| 日韩av成人在线| 中文字幕日韩免费视频| 久久99精品久久久久久琪琪| 亚洲理论片在线观看| 亚洲free嫩bbb| 欧美小视频在线| 91久久精品日日躁夜夜躁国产| 欧美福利小视频| 欧美在线影院在线视频| 欧美亚洲视频一区二区| 91精品国产综合久久久久久蜜臀| 美女久久久久久久| 91国产在线精品| 欧美疯狂xxxx大交乱88av| 久久久久久成人| 日韩av一区在线| 韩剧1988免费观看全集| 亚洲福利在线视频| 最近2019中文免费高清视频观看www99| 亚洲xxxx视频| 久久久午夜视频| 日韩精品在线视频美女| 欧美成人中文字幕在线| 久久躁日日躁aaaaxxxx| 久久琪琪电影院| 91精品国产精品| 国产精品999999| 国产美女精品视频| 国产日本欧美一区| 深夜精品寂寞黄网站在线观看| 国产精品成人免费电影| 欧美日韩亚洲视频一区| 欧美与黑人午夜性猛交久久久| 97人人爽人人喊人人模波多| 国产美女直播视频一区| 久久久91精品国产一区不卡|