簡體   English   中英

使用std :: move以防止復制

[英]using std::move to prevent copying

我有以下代碼:

#include <iostream>
#include <vector>

struct A
{
    std::vector<int> x;

    A()
    {
        std::cout << "A()" << std::endl;
    }

    A(const A&)
    {
        std::cout << "A(const A&)" << std::endl;
    }

    ~A()
    {
        std::cout << "~A()" << std::endl;
    }
};

struct B : public A
{
    std::vector<int> y;

    B()
    {
        std::cout << "B()" << std::endl;
    }

    B(const A&a)
    {
        std::cout << "B(const A&)" << std::endl;
        x = std::move(a.x);
        y.resize(x.size());
    }

    B(const A&&a)
    {
        std::cout << "B(const A&&)" << std::endl;
        x = std::move(a.x);
        y.resize(x.size());
    }
    B(const B&)
    {
        std::cout << "B(const B&)" << std::endl;
    }

    ~B()
    {
        std::cout << "~B()" << std::endl;
    }
};

A ret_a()
{
    A a;
    a.x.resize(10);
    return a;
}

int main()
{
    std::cout << "section I" << std::endl << std::endl;

    A a = ret_a();  
    B b(a);
    std::cout << "a.x.size=" << a.x.size() << std::endl;

    std::cout << std::endl << "section II" << std::endl << std::endl;

    B b2(ret_a());
    std::cout << "b.x.size=" << b.x.size() << std::endl;

    std::cout << std::endl << "section III" << std::endl << std::endl;
    return 0;
}

帶輸出(VS2013,發布版本)

section I

A()
A()
B(const A&)
a.x.size=10

section II

A()
A()
B(const A&&)
~A()
b.x.size=10

section III

~B()
~A()
~B()
~A()
~A()
  1. 為什么“ I部分”中的axsize()的大小為10? 我認為std :: move應該將所有數據從ax移到yx

  2. 為什么“第二節”兩次調用構造函數A()? 我認為B(const A &&)可以防止A的過度復制

UPDATE

請參閱http://pastebin.com/70Nmt9sT上的固定代碼

  1. T&&const T&&不是同一類型。 您幾乎永遠不需要const rvalue引用-自從將其const后就無法竊取其資源! x = std::move(ax); B(const A&a) const vector<int>&&復制ax因為std::move(ax)的返回類型是const vector<int>&&
  2. 構造函數, B(const A&&)調用的默認構造A因為它是衍生自A ,和成員初始化列表不會使試圖構造基A 這是第二個A呼叫。

為什么“ I部分”中的axsize()大小為10? 我認為std::move應該將所有數據從ax移到yx

這是因為B(const A&& a) 由於a是該構造const ,因此您只能對其成員x進行const訪問,並且在vector<T> const上調用std::move導致vector<T> const&&不能綁定到vector的move構造函數(采用vector<T>&&參數)。 相反,它最終調用了復制構造函數,這使源對象保持不變。

為什么“第二節”兩次調用構造函數A() 我認為B(const A&&)可以防止A過度復制

第一個默認構造發生在ret_a()的主體內。 第二種默認構造是BA子對象的構造。 為了避免第二步,在成員初始化器列表中move A實例。

B(const A&&a)
: A(std::move(a))
{
    std::cout << "B(const A&&)" << std::endl;
    y.resize(x.size());
}

需要注意的是, move實際上並沒有導致的內容移動a因同樣的原因如上所述。 此外,即使修改簽名B(A&& a)不會導致內容a移動由於用戶提供拷貝構造函數和析構函數的定義,防止轉移構造的隱代A ,它會被復制而不是。

暫無
暫無

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

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