详细移动语义

Moving semantics in detail

在下面的代码中,与 pm 对齐,该行是否会移动整个内存并将其分配给 pm,或者它只会移动 p 指向的内存而不是整个数组?

   int main()
    {
        int* p{ new int[10]{0} };
        int* pm{ move(p) };//WILL THIS LINE MOVE THE ENTIRE MEMORY ALLOCATED FOR p THAT IS ENTIRE ARRAY or only the memory p is pointing to?
        return 0;
    }

它将指针p复制到指针pm

"Moving" 指针没有意义,因为:

  • 他们没有移动构造函数
  • 他们没有移动赋值运算符
  • 它们非常简单,移动它们没有任何好处

您期望整个数组会以某种方式 "moved" 也没有意义,因为:

  • 您已经只获取了相同数据的句柄,因此无处可移至
  • 类型int*不知道其实例可能指向的数据

请记住,名字可怕的 std::move 实际上并没有移动任何东西。它只是给你一个 rvalue 的名字,否则可能会被视为 lvalue.

在这种情况下,区别是无关紧要的,所以就好像你根本没有写move

移动语义对于间接管理内存的更大、更复杂的对象很有用,例如使用指针。您会期望此类类型的移动构造函数或移动赋值运算符交换指针。就抽象而言,这就是;这就是它的用处。

尝试将相同的逻辑应用于指针本身没有任何意义,除非 unique_ptr 这种抽象以其最纯粹的形式被发现,因为这样的对象是裸指针上的极薄包装。它仍然只是移动的包装器。

您最好的办法是将 p 复制到 pm,然后通过将其设置为某个无法使用的值来任意制作 p "invalid"。再一次,非常没用。

查看 What are move semantics? 了解更多详情。

指针是 "like" 个整数,它们包含 "addresses"。以下代码

int* pm{ move(p) };

在语义上等同于

int* pm = p;

哪个效果就是简单的把p持有的"address"复制到pm中(可以看做整数赋值)

因此 p 指向的内存永远不会是 "moved".

我最喜欢的关于这个主题的演讲之一是 Scott Meyers' An Effective C++11/14 Sampler,他在其中解释了 "std::move() 不移动和 std::forward() 不前进的原因。 ..他们是演员..." ;)