“移动”语义的目的究竟是什么?我知道如果你不通过引用传递非原始类型,就会复制一份副本,但是“移动”如何改变任何东西呢?为什么我们要“移动”数据?为什么不能保持在同一个地址而不进行复制?如果将其发送到另一个地址,这不就是“复制和删除”吗?
简而言之,我真的不明白“移动”语义到底实现了什么。
“移动”语义的目的究竟是什么?我知道如果你不通过引用传递非原始类型,就会复制一份副本,但是“移动”如何改变任何东西呢?为什么我们要“移动”数据?为什么不能保持在同一个地址而不进行复制?如果将其发送到另一个地址,这不就是“复制和删除”吗?
简而言之,我真的不明白“移动”语义到底实现了什么。
移动语义结合了按值传递和按引用传递的优点。您静态分配类,因此无需负责其生命周期,并且可以轻松地将它们作为参数传递并从函数中返回。另一方面,在通常对象被复制的情况下,它们被移动(仅复制它们的内部)。这个操作可能比复制要少花费很多时间(因为您知道,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-value,它将被 移动 到 v
中,这意味着不会发生额外的潜在巨大数组 data_
的复制。