2013-05-29 36 views
3

這個「移動」語義的目的究竟是什麼?我明白如果你不通過引用傳入一個副本是由非原始類型組成的,但「move」如何改變任何東西?我們爲什麼要「移動」數據?爲什麼不能將它保存在同一地址而不能複製?如果它被髮送到另一個地址,是不是隻是一個「複製和刪除」?C++移動語義 - 它究竟要達到什麼目的?

總之,我並沒有真正明白什麼是語義學正在實現。

+2

對我來說很好閱讀http://thbecker.net/articles/rvalue_references/section_01.html –

回答

1

爲什麼不能只是在同一個地址保存,並不會複製

這其實就是移動語義一般不。它經常以完全相同的狀態保存資源(通常是內存,但可以是文件句柄等),但它會更新對象中的引用。

想象兩個向量,srcdestsrc矢量包含在堆上分配的大塊數據,並且dest爲空。當src被移動到dest發生的所有情況是dest被更新爲指向堆上的內存塊,而src被更新爲指向任何dest指向的內容,在這種情況下什麼也沒有。

爲什麼這很有用?因爲這意味着可以寫入vector,只有一個向量會指向它分配的內存塊。這意味着析構函數可以確保它清理已分配的內存。

這可以擴展用於管理其他資源的對象,例如文件句柄。現在可以編寫可擁有文件句柄的對象。這些對象可以移動,但不可複製。由於STL容器支持可移動對象,因此它們可以放在容器中比在C++ 03中容易得多。它們的文件句柄或其他資源只能保證引用它,並且析構函數可以適當地關閉它。

2

移動語義結合了按值傳遞和按引用傳遞的優點。您可以靜態分配類,因此您不必爲其生命週期負責,並且可以將它們作爲參數傳遞並輕鬆地從函數返回。另一方面,在這種情況下,當通常對象被複制時,它們被移動(只複製它們的內部)。此操作可能比複製執行時間少很多(因爲您知道,rhs對象將不再使用)。

MyObj * f() 
{ 
    // Ok, but caller has to take care of 
    // freeing the result 
    return new MyObj(); 
} 

MyObj f() 
{ 
    // Assuming, that MyObj does not have move-ctor 
    // This may be time-costly 
    MyObj result; 
    return result; 
} 

MyObj f() 
{ 
    // This is both fast and safe 
    MyObj result; 
    return std::move(result); 

    // Note, if MyObj implements a move-ctor, 
    // usually you don't have to call std::move. 
} 
0

我與向量代數一個簡單的例子回答:

class Vector{ 
    size_t dim_; 
    double *data_; 
public: 
    Vector(const Vector &arg) 
    : dim_(arg.dim_) 
    , data_(new double[dim_]) 
    { 
    std::copy_n(arg.data_, dim_, data_); 
    } 

    Vector(Vector &&arg) 
    : dim_(arg.dim_) 
    , data_(arg.data_) 
    { 
    arg.data_ = nullptr; 
    } 

    ~Vector() 
    { 
    delete[] data_; 
    } 

    Vector& operator+= (const Vector &arg) 
    { 
    if (arg.dim_ != dim_) throw error; 
    for (size_t idx = 0; idx < dim_; ++idx) data_[idx] += arg.data_[idx]; 
    return *this; 
    } 
}; 

Vector operator+ (Vector a, const Vector &b) 
{ 
    a += b; 
    return a; 
} 

extern Vector v1, v2; 

int main() 
{ 
    Vector v(v1 + v2); 
} 

添加按值返回一個新的載體。因爲它是一個r值,所以轉換爲v,這意味着將不會發生潛在巨大數組data_的額外副本。