C++11 move记录

说到C++11新增的move,得先说一下左值和右值。
比如int a = 1; int b = a;我们说在b=a中,a是左值,因为它有名字,在之后还可以访问到;
int a = 1; int b = a + c;这里得a+c就是右值,它是一个临时变量,没有名字,所以之后无法对它进行访问。

对于移动构造函数(move constructor)

#include <cstring>
#include <algorithm>

class string
{
    char* data;

public:

    string(const char* p)
    {
        size_t size = std::strlen(p) + 1;
        data = new char[size];
        std::memcpy(data, p, size);
    }
    ~string()
    {
        delete[] data;
    }

    string(const string& that)
    {
        size_t size = std::strlen(that.data) + 1;
        data = new char[size];
        std::memcpy(data, that.data, size);
    }
     

上述例程中的拷贝构造函数(copy constructor)是一个深拷贝,我们在堆上开辟新的内存空间,然后将that的数据一一拷贝过来。

对于左值,使用拷贝构造函数是必须的。比如string a(x);,因为我们之后还可能继续访问x
对于右值,比如string b(x+y);或者string c(some_function_returning_a_string());x+ysome_function_returning_a_string()这样的临时变量在之后不能被访问到,在下一个语句时就会被析构掉,那为何不好好利用起来呢?因为对于右值,我们不直接深拷贝堆数据,而是直接拷贝这个临时变量的数据指针。具体如下

string(string&& that)   // string&& is an rvalue reference to a string
{
    data = that.data;
    that.data = nullptr;
}

因为这并不是拷贝,所以称为移动构造(move constructor)。

参考

What is move semantics?

posted @ 2020-03-17 22:49  Lo3King  阅读(151)  评论(0编辑  收藏  举报