C++中的std::move函数

本文内容概览

在使用C++的过程中,我们可能都接触过移动构造函数(Move constructor),在使用移动构造函数的过程中,有一个很重要的函数 std::move() ,本文将详细介绍这一内容:

std::move() 是什么

从技术上来看, std::move() 是一个函数,但或许它并不是一个真正的函数。它更像是一个转换器,在编译器考虑表达式值的方式之间进行转换。

std::move() 做了什么

首先要注意的是,std::move() 实际上并没有移动任何东西。它将表达式从左值(lvalue)(例如命名变量)转换为x值(xvalue)。x值告诉编译器:

你可以掠夺、移动我持有的任何东西并在别处使用(反正我很快就会被销毁)。1

换句话说,当你使用 std::move(x) 时,本质上是允许编译器对 x 拥有的资源进行利用。因此,如果 x 有自己的内存缓冲区,那么在 std::move(x) 之后,这块资源将被 x 释放,编译器可以将其分配给另一个对象。

std::move() 什么时候用

这一问题等价于“什么时候我要利用现有对象的资源?”,在构造函数、运算符方法等地方经常需要这样做,因为在这些地方对象会自动频繁地创建和销毁。当然,这只是一个经验法则。

一个典型的用例是将资源从一个对象“移动”到另一个对象,而不是复制。下面给出一个简单直接的示例:以更少的复制交换两个对象。

如果使用拷贝构造函数:

template <class T>
swap(T& a, T& b) {
    T tmp(a);   // 我们创建了a的第二份副本
    a = b;      // 我们创建了b的第二份副本(并丢弃了a的副本)
    b = tmp;    // 我们创建了tmp的第二份副本(并丢弃了b的副本)
}

而当我们使用 std::move 方法,我们就可以做到交换资源而不是到处复制它们:

template <class T>
swap(T& a, T& b) {
    T tmp(std::move(a));
    a = std::move(b);   
    b = std::move(tmp);
}

设想,当T 是一个大小为 n 的 vector<int> 时会发生什么。在第一个版本中,你需要读取和写入 3 * n 个元素,而在第二个版本中,你基本上只需要读取和写入指向 vector 缓冲区的 3 个指针,加上 3 个缓冲区的大小。当然,类 T 需要知道如何进行移动操作;为了使其工作,你的类需要有一个移动赋值运算符和一个移动构造函数。

参考资料

[1]: https://stackoverflow.com/questions/3413470/what-is-stdmove-and-when-should-it-be-used
[2]: https://web.stanford.edu/class/cs106l/lectures/13_Move_Semantics_S24.pdf


  1. https://en.cppreference.com/w/cpp/language/value_category ↩︎

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值