back

C++ 胡言乱语X2

子标题:理解 std::move 和所有权。

前言

关于 std::move 其实也有很多文章了,不过为了给群友解释,再造一次轮子。

std::move

我们打开 std::move 的实现,发现里面是一个强制类型转换(随便找的代码)。

template <typename T>
typename remove_reference<T>::type&& move(T&& arg)
{
    return static_cast<typename remove_reference<T>::type&&>(arg);
}

使用:

Object A;
Object B = std::move(A);

这右值有啥用啊?假设 Object 类有以下构造函数:

// 函数1
Object(const Object& object);
// 函数2
Object(Object&& object);

如果没有std::move(A)这一步,那么B将会调用函数1进行构造,反之调用函数2。

但分开两个构造函数是干什么呢,这里就牵涉到一个资源分配和所有权问题。

所有权

假如你是A,你从宠物商店买了一只仓鼠回来(仓鼠挺可爱的),那你就成为了这只仓鼠的主人。

B是你的好朋友,他经常到你家玩。他觉得你的仓鼠很可爱,于是他也想买一只,但是他没有足够的钱。

  • 分支路线1:

可是突然有一天,你不想养这只仓鼠了,就想找个人帮你继续养下去。你知道B也想养一只属于自己的仓鼠,但没有钱去买。于是你找来了B,将仓鼠送给了他。

那么B从这天起,就成为了仓鼠的第二任主人了。

  • 分支路线2:

有一天B打工赚了许多钱,于是他去问你这只仓鼠是什么品种,然后自己到宠物商店买了一只差不多一样的。

现在又有一只小仓鼠找到了新家了。


回到主题,在上面,抽象来讲,买了一只仓鼠,其实就是分配了一个资源,你就拥有了他的使用权(所有权)。

分支路线1中,A把仓鼠送给了B,这就是转移了仓鼠的所有权,主人从A变成了B,对应Object(Object&& object)

分支路线2中,B也买了一只仓鼠,这样两只仓鼠,都有了各自的主人,对应Object(const Object& object)

要知道买一只新仓鼠是要花钱的,所以在某些场景用 std::move 来节省这个资源的开销。

但仓鼠毕竟是别人养过的,想要一只独一无二属于自己的小仓鼠,那就买一只新的吧,所以就需要申请一份新的资源

后记

理解所有权后,就像学数据结构学会了链表。学习新的知识,第一步总是最难的。