日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

详解C++移动语义std::move()

發布時間:2025/3/15 c/c++ 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 详解C++移动语义std::move() 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

目錄

1. C++move的概念

2. C++move的特點

3. 左值、右值與左值引用、右值引用

3.1 左值和右值的概念

3.2 左值引用和右值引用

4. std::move詳解

4.1 std::move簡介

4.2 std::move詳解

4.3 std::move實現:

4.4 std::move的優點

4.5??std::move的使用


參考:

https://blog.csdn.net/s11show_163/article/details/114296006

https://blog.csdn.net/daaikuaichuan/article/details/88371948
https://zhuanlan.zhihu.com/p/94588204
https://www.cnblogs.com/SZxiaochun/p/8017475.html
https://www.cnblogs.com/yoyo-sincerely/p/8658075.html
左值引用與右值引用,以及為什么右值引用本身是左值的問題詳見:https://www.cnblogs.com/char-cheng/p/11026936.html

1. C++move的概念

一句話概括std::move ———— std::move是將對象的狀態或者所有權從一個對象轉移到另一個對象,只是轉移,沒有內存的搬遷或者內存拷貝。

2. C++move的特點

  • std::move函數可以以非常簡單的方式將左值引用轉換為右值引用。(左值、左值引用、右值、右值引用 參見:http://www.cnblogs.com/SZxiaochun/p/8017475.html)
  • ?通過std::move,可以避免不必要的拷貝操作。
  • std::move是為性能而生。
  • std::move是將對象的狀態或者所有權從一個對象轉移到另一個對象,只是轉移,沒有內存的搬遷或者內存拷貝。
  • 如string類在賦值或者拷貝構造函數中會聲明char數組來存放數據,然后把原string中的 char 數組被析構函數釋放,如果a是一個臨時變量,則上面的拷貝,析構就是多余的,完全可以把臨時變量a中的數據直接 “轉移” 到新的變量下面即可。
  • 3. 左值、右值與左值引用、右值引用

    右值引用(及其支持的Move語意和完美轉發)是C++0x加入的最重大語言特性之一。從實踐角度講,它能夠完美解決C++中長久以來為人所詬病的臨時對象效率問題。從語言本身講,它健全了C++中的引用類型在左值右值方面的缺陷。從庫設計者的角度講,它給庫設計者又帶來了一把利器。從庫使用者的角度講,不動一兵一卒便可以獲得“免費的”效率提升。

    3.1 左值和右值的概念

  • 左值是可以放在賦值號左邊可以被賦值的值;左值必須要在內存中有實體;
  • 右值當在賦值號右邊取出值賦給其他變量的值;右值可以在內存也可以在CPU寄存器。
  • 一個對象被用作右值時,使用的是它的內容(值),被當作左值時,使用的是它的地址。
  • 左值:指表達式結束后依然存在的持久對象,可以取地址,具名變量或對象 。
  • 右值:表達式結束后就不再存在的臨時對象,不可以取地址,沒有名字。
  • int a; int b;a = 3; b = 4; a = b; b = a;// 以下寫法不合法。 3 = a; a + b = 4;

    3.2 左值引用和右值引用

    引用是C++語法做的優化,引用的本質還是靠指針來實現的。引用相當于變量的別名。引用可以改變指針的指向,還可以改變指針所指向的值。

    左值引用:type &引用名 = 左值表達式;就是對左值的引用 就是給左值取別名

    右值引用:type &&引用名 = 右值表達式;就是對右值的引用 就是給右值取別名

    int a=10; //a 是左值 double b=1.3; //b 是左值 //左值引用 int & Ta=a; //引用左值 故 是一個左值引用 double & Tb=b; //引用左值 故是一個左值引用

    再比如:

    int a = 100; int&& b = 100;//右值引用 int& c = b; //正確,b為左值 int& d = 100; //錯誤

    4. std::move詳解

    4.1 std::move簡介

    在C++11中,標準庫在中提供了一個有用的函數std::move,std::move并不能移動任何東西,它唯一的功能是將一個左值引用強制轉化為右值引用,繼而可以通過右值引用使用該值,以用于移動語義。從實現上講,std::move基本等同于一個類型轉換:static_cast<T&&>(lvalue);

    #include <iostream> #include <utility> #include <vector> #include <string> int main() {std::string str = "Hello";std::vector<std::string> v;//調用常規的拷貝構造函數,新建字符數組,拷貝數據v.push_back(str);std::cout << "After copy, str is \"" << str << "\"\n"; //str輸出為"Hello"//調用移動構造函數,掏空str,掏空后,最好不要使用strv.push_back(std::move(str));std::cout << "After move, str is \"" << str << "\"\n"; //str輸出為空std::cout << "The contents of the vector are \"" << v[0]<< "\", \"" << v[1] << "\"\n";//v[0]、v[1]都為"Hello" }

    輸出

    After copy, str is "Hello" After move, str is "" The contents of the vector are "Hello", "Hello"


    4.2 std::move詳解

    std::move 的函數原型定義:

    template <typename T> typename remove_reference<T>::type&& move(T&& t) {return static_cast<typename remove_reference<T>::type &&>(t); }

    首先,函數參數T&&是一個指向模板類型參數的右值引用,通過引用折疊,此參數可以與任何類型的實參匹配(可以傳遞左值或右值,這是std::move主要使用的兩種場景)。關于引用折疊如下:

    所有右值引用折疊到右值引用上仍然是一個右值引用。(A&& && 變成 A&&) 。
    所有的其他引用類型之間的折疊都將變成左值引用。 (A& & 變成 A&; A& && 變成 A&; A&& & 變成 A&)。

    簡單來說,右值經過T&&傳遞類型保持不變還是右值,而左值經過T&&變為普通的左值引用。

    //原始的,最通用的版本 template <typename T> struct remove_reference{typedef T type; //定義T的類型別名為type };//部分版本特例化,將用于左值引用和右值引用 template <class T> struct remove_reference<T&> //左值引用 { typedef T type; }template <class T> struct remove_reference<T&&> //右值引用 { typedef T type; } //舉例如下,下列定義的a、b、c三個變量都是int類型 int i; remove_refrence<decltype(42)>::type a; //使用原版本, remove_refrence<decltype(i)>::type b; //左值引用特例版本 remove_refrence<decltype(std::move(i))>::type b; //右值引用特例版本

    4.3 std::move實現:

    1. 首先,通過右值引用傳遞模板實現,利用引用折疊原理將右值經過T&&傳遞類型保持不變還是右值,而左值經過T&&變為普通的左值引用,以保證模板可以傳遞任意實參,且保持類型不變。(cpr:先能夠把參數類型全都接收)
    2. 然后我們通過static_cast<>進行強制類型轉換返回T&&右值引用,而static_cast之所以能使用類型轉換,是通過remove_refrence::type模板移除T&&,T&的引用,獲取具體類型T(模板偏特化)。(cpr:再把接收的參數的原引用抹除強轉成右引)

    4.4 std::move的優點

    std::move語句可以將左值變為右值而避免拷貝構造。

    std::move是將對象的狀態或者所有權從一個對象轉移到另一個對象,只是轉移,沒有內存的搬遷或者內存拷貝。

    4.5??std::move的使用

    比如向vector中插入新元素。

    int a = 1; vector<int> vec; vec.push_back(move(a));

    總結

    以上是生活随笔為你收集整理的详解C++移动语义std::move()的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 亚洲欧美日韩一区二区 | av免费在线观看不卡 | 日韩在线一区二区三区 | 在线观看一区 | 亚洲精品日韩精品 | 99国产精品99久久久久久 | 最新毛片基地 | 国产第一区第二区 | 短视频在线观看 | 网站国产| 亚洲老女人视频 | 午夜在线视频 | 在线视频久 | 亚洲高清在线 | 国内自拍av| 亚洲精品视频在线看 | 日韩免费在线看 | 在线观看你懂得 | 高清中文字幕在线a片 | 小早川怜子久久精品中文字幕 | 亚洲淫欲 | av卡一卡二 | 国产激情久久 | 97超碰超碰 | 草草草在线视频 | 青青草在线免费观看 | 国产ts在线视频 | 天天操夜夜摸 | 日日噜 | 亚洲福利在线播放 | 日本黄色免费观看 | 国产精品美女久久久免费 | 老司机深夜视频 | 丁香花电影高清在线阅读免费 | 九色国产视频 | 国产秋霞| 国产精品对白刺激久久久 | 亲子乱一区二区三区 | 第一页在线 | 性中国xxx极品hd | 九九在线精品视频 | 欧美天天射 | 在线看日本 | 欧美日韩一区二区久久 | 精品欧美一区二区三区在线观看 | 特黄一区二区 | 在线观看aa | 97国产超碰 | 国产精品久久久999 www日本高清视频 | 日韩免费观看一区二区 | 人妻丰满熟妇av无码区不卡 | 国产精品电影一区二区三区 | 可以免费看的黄色网址 | 一区二区伦理片 | 岛国av毛片 | 青青操狠狠干 | 97av视频在线 | 丝袜诱惑一区 | 国产精品香蕉 | 毛片网站免费在线观看 | 丰满熟妇人妻av无码区 | 久久精品中文字幕 | 蜜桃av网| 免费视频污 | 国产情侣小视频 | 亚洲AV无码乱码国产精品牛牛 | 日韩美女福利视频 | 久久视频精品在线 | 亚洲综合视频一区 | av网址网站 | 香蕉久久夜色精品国产使用方法 | 日韩国产欧美视频 | 激情网色| 加勒比毛片| 久久中文字幕国产 | 久久中文一区 | 日本在线视频不卡 | 婷婷资源网 | 久久久久毛片 | 国产精品免费视频一区二区 | 黄色在线小视频 | 日本天堂网在线 | 91免费在线| 天天综合天天做天天综合 | 欧美成人生活片 | 玖玖成人 | 成人av资源站| 黄片毛片在线 | 欧美国产成人在线 | 精品国产鲁一鲁一区二区三区 | 饥渴少妇色诱水电工 | 久久久久久国产免费a片 | 黄色免费网站在线 | 成人免费毛片嘿嘿连载视频 | 欧美a级片视频 | 日韩一二三区 | 日本黄色天堂 | 久久精品色欲国产AV一区二区 | 亚洲精品大片 |