這個「移動」語義的目的究竟是什麼?我明白如果你不通過引用傳入一個副本是由非原始類型組成的,但「move」如何改變任何東西?我們爲什麼要「移動」數據?爲什麼不能將它保存在同一地址而不能複製?如果它被髮送到另一個地址,是不是隻是一個「複製和刪除」?C++移動語義 - 它究竟要達到什麼目的?
總之,我並沒有真正明白什麼是語義學正在實現。
這個「移動」語義的目的究竟是什麼?我明白如果你不通過引用傳入一個副本是由非原始類型組成的,但「move」如何改變任何東西?我們爲什麼要「移動」數據?爲什麼不能將它保存在同一地址而不能複製?如果它被髮送到另一個地址,是不是隻是一個「複製和刪除」?C++移動語義 - 它究竟要達到什麼目的?
總之,我並沒有真正明白什麼是語義學正在實現。
爲什麼不能只是在同一個地址保存,並不會複製
這其實就是移動語義一般不。它經常以完全相同的狀態保存資源(通常是內存,但可以是文件句柄等),但它會更新對象中的引用。
想象兩個向量,src
和dest
。 src
矢量包含在堆上分配的大塊數據,並且dest
爲空。當src
被移動到dest
發生的所有情況是dest
被更新爲指向堆上的內存塊,而src
被更新爲指向任何dest
指向的內容,在這種情況下什麼也沒有。
爲什麼這很有用?因爲這意味着可以寫入vector
,只有一個向量會指向它分配的內存塊。這意味着析構函數可以確保它清理已分配的內存。
這可以擴展用於管理其他資源的對象,例如文件句柄。現在可以編寫可擁有文件句柄的對象。這些對象可以移動,但不可複製。由於STL容器支持可移動對象,因此它們可以放在容器中比在C++ 03中容易得多。它們的文件句柄或其他資源只能保證引用它,並且析構函數可以適當地關閉它。
移動語義結合了按值傳遞和按引用傳遞的優點。您可以靜態分配類,因此您不必爲其生命週期負責,並且可以將它們作爲參數傳遞並輕鬆地從函數返回。另一方面,在這種情況下,當通常對象被複制時,它們被移動(只複製它們的內部)。此操作可能比複製執行時間少很多(因爲您知道,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.
}
我與向量代數一個簡單的例子回答:
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_
的額外副本。
對我來說很好閱讀http://thbecker.net/articles/rvalue_references/section_01.html –