c++之右值与移动语义

        左值 lvalue 是有标识符、可以取地址的表达式。字符串字面量是左值,在C++中 字符串其实是const char[N],其实是个常量表达式,在内存中有明确的地址。

        纯右值 prvalue 是没有标识符、不可以取地址的表达式,一般也称之为“临时对象”。

        需要注意的是类型是右值引用的变量是一个左值。毕竟对于一个右值引用的变量,你是可以取地址的,这点上它和左值完全一致。

    std::move(ptr) 就有趣点了。它的作用是把一个左值引用强制转换成一个右值引用,而并不改变其内容,结果是指向 ptr的一个右值引用。我们可以把 std::move(ptr) 看作是一个有名字的rvalue。为了跟无名的纯右值 prvalue 相区别,C++ 里目前就把这种表达式叫做 xvalue。跟左值 lvalue 不同,xvalue 仍然是不能取地址的——这点上,xvalue 和 prvalue 相同。所以,xvalue 和 prvalue 都被归为右值 rvalue。如果一个 prvalue 被绑定到一个引用上,它的生命周期则会延长到跟这个引用变量一样长。

        移动语义

       使得在 C++ 里返回大对象(如容器)的函数和运算符成为现实,因而可以提高代码的简洁性和可读性,提高程序员的生产率。

        对于 template foo(T&&) 这样的代码,如果传递过去的参数是左值,T 的推导结果是左值引用;如果传递过去的参数是右值,T 的推导结果是参数的类型本身。
如果 T 是左值引用,那 T&& 的结果仍然是左值引用——即 type& && 坍缩成了 type&。
如果 T 是一个实际类型,那 T&& 的结果自然就是一个右值引用。

         如何实现移动?

要让你设计的对象支持移动的话,通常需要下面几步:

  • 你的对象应该有分开的拷贝构造和移动构造函数(除非你只打算支持移动,不支持拷贝——如 unique_ptr)。
  • 你的对象应该有 swap 成员函数,支持和另外一个对象快速交换成员。
  • 在你的对象的名空间下,应当有一个全局的 swap 函数,调用成员函数 swap 来实现交换。支持这种用法会方便别人(包括你自己在将来)在其他对象里包含你的对象,并快速实现它们的 swap 函数。
  • 实现通用的 operator=
  • 上面各个函数如果不抛异常的话,应当标为 noexcept。这对移动构造函数尤为重要

你可能感兴趣的:(C++,c++,开发语言,后端)