移动语义是什么?

2080
我刚刚听完了关于C++11的软件工程广播采访Scott Meyers。其中大部分新特性对我来说都很有意义,只有一个例外。我还是不太明白移动语义...它到底是什么?

28
我找到了Eli Bendersky的博客文章,它介绍了C和C++中lvalue和rvalue的概念,并提到了C++11中的rvalue引用,通过一些小例子对其进行了介绍。 - Nils
23
Alex Allain对这个主题的阐述非常精彩。 - Patrick Sanan
43
每年左右,我都会想知道C++中的“新”移动语义是什么,于是我谷歌了一下并找到了这个页面。我读了回答,但我的大脑变得迷茫了。然后我就回到C语言,把一切都忘了!我被卡住了。 - sky
19
考虑使用 std::vector<>... 其中有一个指针指向堆上的数组。如果您复制此对象,则必须分配一个新缓冲区,并将缓冲区中的数据复制到新缓冲区。是否有什么情况可以简单地窃取指针?答案是肯定的,当编译器知道对象是临时的时候。移动语义允许您定义如何将类的内容移出并放入不同的对象中,当编译器知道要移动的对象即将消失时。 - dicroce
2
我能理解的唯一参考资料是:https://www.learncpp.com/cpp-tutorial/15-1-intro-to-smart-pointers-move-semantics/,即移动语义的原始推理来自智能指针。 - jw_
显示剩余2条评论
11个回答

-2

以下是来自Bjarne Stroustrup的书《C++编程语言》中的一个答案。如果您不想观看视频,可以查看下面的文字:

考虑这个片段。从operator+返回涉及将结果从局部变量res复制到某个调用者可以访问它的地方。

Vector operator+(const Vector& a, const Vector& b)
{
    if (a.size()!=b.size())
        throw Vector_siz e_mismatch{};
    Vector res(a.size());
        for (int i=0; i!=a.size(); ++i)
            res[i]=a[i]+b[i];
    return res;
}

我们其实并不想要一个副本;我们只是想从函数中获得结果。所以我们需要移动一个向量而不是复制它。我们可以定义移动构造函数如下:

class Vector {
    // ...
    Vector(const Vector& a); // copy constructor
    Vector& operator=(const Vector& a); // copy assignment
    Vector(Vector&& a); // move constructor
    Vector& operator=(Vector&& a); // move assignment
};

Vector::Vector(Vector&& a)
    :elem{a.elem}, // "grab the elements" from a
    sz{a.sz}
{
    a.elem = nullptr; // now a has no elements
    a.sz = 0;
}

&& 表示“右值引用”,是一个引用,我们可以将其绑定到右值上。 "rvalue" 的意思是补充 "lvalue",它大致意味着 "可以出现在赋值的左侧的东西"。因此,rvalue 大致意味着 "无法分配的值",例如函数调用返回的整数和 Vector 中 operator+() 的 res 局部变量。

现在,语句 return res; 将不会复制!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接