在C++11中,标准库在<utility>中提供了一个有用的函数std::move,这个函数的名字具有迷惑性,因为实际上std::move并不能移动任何东西,它唯一的功能是将一个左值强制转化为右值引用,继而我们可以通过右值引用使用该值,以用于移动语义。从实现上讲,std::move基本等同于一个类型转换:
static_cast<T&&>(lvalue);
值得一提的是,被转化的左值,其生命期并没有随着左右值的转化而改变。
#include <iostream> using namespace std; class Moveable{ public: Moveable():i(new int(3)) {} ~Moveable() { delete i; } Moveable(const Moveable & m): i(new int(*m.i)) { } Moveable(Moveable && m):i(m.i) { m.i = nullptr; } int* i; }; int main() { Moveable a; Moveable c(move(a)); // 会调用移动构造函数 cout << *a.i << endl; // 运行时错误 }
上例中,我们为类型Moveable定义了移动构造函数。这个函数定义本身没有什么问题,但调用的时候,使用了Moveable c(move(a));这样的语句。这里的a本来是一个左值变量,通过std::move将其转换为右值。这样一来,a.i就被c的移动构造函数设置为指针空值。由于a的生命期实际要到main函数结束才结束,那么随后对表达式*a.i进行计算的时候,就会发生严重的运行时错误(此处为了说明std::move()的特点:将一个左值强制转化为右值引用)。
调用move就意味着承诺:除了对a赋值或销毁它外,我们将不再使用它。
原文地址:https://www.cnblogs.com/Stephen-Qin/p/9082190.html
时间: 2024-10-07 20:05:32