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

歡迎訪問 生活随笔!

生活随笔

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

c/c++

C++11:move移动语义

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

前言

我們知道移動語義是通過右值引用來匹配臨時值,那么,普通的左值是否也能借助移動語義來優化性能呢,C++11為了解決這個問題,提供了std::move方法來將左值轉換成右值。

正文

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

move實際上并不能移動任何東西,它只是將一個左值強制轉換成一個右值引用,使我們可以通過右值引用使用該值,以用于移動語義,強制轉換為右值的目的是為了方便實現移動構造。

這種move語義是很有用的,比如一個對象中有一些指針資源或者動態數組,在對象的賦值或者拷貝時就不需要拷貝這些資源了。在C++11之前拷貝構造函數和賦值函數可能要像下面這樣定義。假設A對象內部有一個資源m_ptr:

A & A::operator=(const A &rhs) { //銷毀m_ptr指向的資源 //復制rhs.m_ptr所指向的資源,并使m_ptr指向它 }

通過A的拷貝構造函數也是這樣,假設這樣來使用A:

A foo(); A a; a = foo();

最后一行將會發生如下操作:

  • 銷毀a所持有的資源
  • 復制foo返回的臨時對象所擁有的資源
  • 銷毀臨時對象,釋放其資源

上面的辦法是可行的,但是更有效的方法是直接交換a和臨時對象中的資源指針,然后讓臨時對象的析構函數去銷毀a原來擁有的資源。當復制操作符的右邊是右值的時候,我們希望賦值操作符被定義成下面這樣:

A & A::operator=const A &&rhs) { //轉移資源的控制權,無需復制 }

僅僅轉移資源的所有者,將資源的擁有者改為被賦值者,這就是move語義。

如下示例,假設一個臨時容器很大,賦值給另一個容器:

{std::list<std::string> arrs; //省略初始化std::list<std::string> temp = arrs; }std::list<std::string> arrs; std::list<std::string> temp = std::move(arrs);

如果這里不用move,拷貝的代價很大,性能較低。而使用move幾乎沒有任何代價,只是將資源的所有權轉移了,實際上是將左值變成了右值引用,然后應用move語義調用構造函數,這樣避免了拷貝,提高程序性能。

當一個對象內部有較大的堆內存或者動態數組時,很有必要寫move語義的拷貝構造函數和賦值函數,避免無謂的深拷貝,以提高性能。

注意:move對于擁有形如對內存、文件句柄等子資源的成員的對象有效,如果是一些基本類型, 如int和char[4]數組時,如果使用move,仍然會發生拷貝(因為沒有對應的移動構造函數),所以說move對于含資源的對象來說更有意義。

參考:《深入應用C++11》

總結

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

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