簡體   English   中英

C++11 移動語義行為特定問題

[英]C++11 Move semantics behaviour specific questions

我已經閱讀了下面的帖子,它對移動語義有很好的了解:

有人可以向我解釋移動語義嗎?

但我仍然無法理解有關移動語義的以下內容-

  1. 復制省略和 RVO 是否仍然適用於沒有移動構造函數的類?

  2. 即使我們的類沒有移動構造函數,但 STL 容器有一個。 對於像這樣的操作

std::vector<MyClass> vt = CreateMyClassVector();

並執行排序等操作。為什么 STL 不能在內部利用移動語義來在內部使用不需要移動構造函數的復制省略或 RVO 等操作來改進此類操作?

3. 在下面的情況下,我們是否從移動語義中受益 -

std::vector< int > vt1(1000000, 5); // Create and initialize 1 million entries with value 5

std::vector< int > vt2(std::move(vt1)); // move vt1 to vt2

由於整數是一種原始類型,移動整數元素不會提供任何優勢。 或者在移動操作之后 vt2 簡單地指向堆中的 vt1 內存並且 vt1 設置為空。 實際發生了什么? 如果是后者,那么即使是第 2 點也認為我們可能不需要為我們的類移動構造函數。

4. 當在左值上使用 std::move 調用 push_back() 時,例如:

    std::vector<MyClass> vt;

    for(int i=0; i<10; ++i)
    {
        vt.push_back(MyClass());
    }

    MyClass obj;

    vt.push_back(std::move(obj));

現在,由於向量具有連續的內存分配,並且 obj 在內存中的其他地方定義通過簡單地移動指向堆不同區域中的內存的指針來向量連續內存需求。?

感謝您提前解釋!

[最初發布為Move 語義澄清,但現在隨着上下文的變化,將其發布為新問題應盡快刪除舊問題。]

復制省略和 RVO 是否仍然適用於沒有移動構造函數的類?

是的,RVO 仍然有效。實際上,編譯器應該選擇:

  • RVO(如果可能)
  • 移動建築(如果可能)
  • 復制構造(最后的手段)

為什么 STL 不能在內部利用移動語義來在內部使用不需要移動構造函數的復制省略或 RVO 等操作來改進此類操作?

STL 容器可移動的,與存儲在其中的類型無關。 然而,容器中的對象操作需要的對象合作,這樣的排序(例如),如果這些對象是可移動可能只移動對象。

在下面的情況下,我們是否從移動語義中受益 [...] 因為整數是原始類型?

是的,你會這樣做,因為容器可移動的,無論其內容如何。 正如您推斷的那樣, st2將從st1竊取內存。 移動后st1的狀態是未指定的,所以我不能保證它的存儲將被取消。

當在左值上使用std::move調用push_back() [會發生什么]?

調用左值類型的移動構造函數,通常這涉及將原件按位復制到目標中,然后取消原件。

通常,移動構造函數的成本與sizeof(object)成正比; 例如,無論std::string有多少個字符, sizeof(std::string)都是穩定的,因為實際上這些字符存儲在堆上(至少當它們有足夠數量時),因此只有指向堆存儲的指針被移動(加上一些元數據)。

  1. 是的。
  2. 他們盡可能這樣做。
  3. 是的。 std::vector有一個移動構造函數,可以避免復制所有元素。
  4. 它仍然是連續的。

例如

struct MyClass
{         
     MyClass(MyClass&& other) 
         : xs(other.xs), size(other.size)
     {
          other.xs = nullptr;
     }

     MyClass(const MyClass& other) 
       : xs(new int[other.size]), size(other.size)
     { 
         memcpy(xs, other.xs, size);
     }

     ~MyClass() 
     {               
         delete[] xs;
     }

     int* xs;
     int size;
}

使用移動構造函數只需要將xssize復制到向量中(對於連續內存),但是我們不需要像復制構造函數中那樣執行內存分配和memcpy

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM