强制转换为右值

在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赋值或销毁它外,我们将不再使用它。

猜你喜欢

转载自www.cnblogs.com/Stephen-Qin/p/9082190.html
今日推荐