为什么C ++移动语义会使源构建完毕?

时间:2015-10-31 18:25:32

标签: c++ c++11 move-semantics

在C ++ 11中,引入了“移动语义”,通过两个特殊成员实现:移动构造函数和移动赋值。这两个操作都将构建移动的对象。

将源保持在破坏状态不是更好吗?对于移动对象,你唯一能做的就是破坏它吗?

1 个答案:

答案 0 :(得分:26)

在“移动操作领域”中有四种可能性:

target          source
  is            is left
----------------------------------------------------------
constructed <-- constructed  // C++11 -- move construction
constructed <-- destructed
assigned    <-- constructed  // C++11 -- move assignment
assigned    <-- destructed

这些操作中的每一个都有用!仅std::vector<T>::insert就可以利用前三个。虽然注意:

  • 第二个和第四个的来源不应具有自动,静态或线程存储持续时间。源的存储持续时间必须是动态的,否则编译器将在已经被破坏的对象上调用析构函数。不,编译器不能(通常)跟踪对象是否已被移动:
X x1, x2;
if (sometimes)
{
    x1 = std::move(x2);
}
// Is x2 moved-from here?
  • 第二个和第四个分别可以通过第一个和第三个来模拟,只需在操作后手动调用源上的析构函数即可。

  • 第一和第三是至关重要的。诸如std::swapstd::sort之类的算法经常需要这两种操作。这些算法不需要破坏任何输入对象 - 只需更改它们的值。

有了这些知识,在2001 - 2002年的时间框架内,我将我的工作集中在两个操作上,这两个操作都是由于这两个操作对C ++ 98的影响最大(正面)。我当时知道,如果我没有减少这个项目的野心,它将永远不会成功。即使受到限制,但要成功还是过于雄心勃勃。

此缩减在the original move semantics proposal中标题为“破坏性移动语义”的部分中得到承认。

  

最后,我们只是放弃了这个因为太多的痛苦   足够的收益。但是,目前的提案并未禁止   未来的破坏性移动语义。它可以在   除了这里概述的非破坏性移动语义   如果有人希望携带火炬,建议。

有关移动对象可以执行的操作的详细信息,请参阅https://stackoverflow.com/a/7028318/576911