C++中的移动构造函数和移动赋值运算符

C++中的移动构造函数和移动赋值运算符

移动构造函数是一个特殊的构造函数,它能够从一个右值引用(rvalue reference)创建新的对象,而无需进行深拷贝(deep copy)。我们可以将移动构造函数比喻成搬家时的快递员。

假设你搬家,有一堆家具需要装进卡车。传统的深拷贝(复制构造函数)就像是你把每一件家具都精心地复制一份,然后放进卡车上。这个过程费时费力,而且你原本的家具还要保留。

但是,如果你找来一位勇敢的快递员(移动构造函数),他们可以直接将你的家具移动到新的屋子里,而不用复制。这样,节省了时间和精力,而且你原本的家具可以顺利放进新的屋子。

在代码中,移动构造函数使用右值引用作为参数,并且我们将原始对象的资源直接转移到新对象中,而不是进行复制。这就如同快递员将家具从旧的房子搬到新的房子中,节省了时间和空间开销。

总的来说:可以理解为快速的拷贝构造函数

移动赋值操作符允许我们将一个对象的资源转移到另一个对象上。可以把移动赋值操作符比喻成两个人交换工作岗位。

想象一下,你在一家公司工作,有一天你被调往另外一个部门。传统的方式是,你将自己的工作内容复制一份,再将新工作的内容复制回来,形成了两份一样的工作内容。这样的操作显然很冗余。

然而,通过移动赋值操作符,你可以直接将自己的工作内容交给新的员工,并且接管他们原本的工作,省去了不必要的复制步骤。

在代码中,移动赋值操作符也使用右值引用作为参数。我们将源对象的资源直接转移到目标对象中,同时将源对象恢复到一种可安全销毁或重新赋值的状态。这就如同两个人交换工作岗位,互相拥有对方的资源和责任。

总的来说:可以理解为快速的赋值运算符。(比一般的更快,因为无需深拷贝)

移动构造函数的声明语法如下:

class Sample
{
private:
    Type* ptrResource;
    
public:
    Sample(Sample&& moveSource) // Move constructor, note &&
    {
        ptrResource = moveSource.ptrResource; // take ownership, start move
        moveSource.ptrResource = NULL;
    }
    Sample& operator= (Sample&& moveSource)//move assignment operator, note &&
    {
        if(this != &moveSource)
        {
            delete [] ptrResource; // free own resource
            ptrResource = moveSource.ptrResource; // take ownership, start move
            moveSource.ptrResource = NULL; // free move source of ownership
        }
    }
    Sample(); // default constructor
    Sample(const Sample& copySource); // copy constructor
    Sample& operator= (const Sample& copySource); // copy assignment
};

从上述代码可知,相比于常规赋值构造函数和复制赋值运算符的声明,移动构造函数和移动赋值
运算符的不同之处在于,输入参数的类型为 Sample&&。另外,由于输入参数是要移动的源对象,因
此不能使用 const 进行限定,因为它将被修改。返回类型没有变,因为它们分别是构造函数和赋值运算
符的重载版本。
在需要创建临时右值时,遵循 C++的编译器将使用移动构造函数(而不是复制构造函数)和移动
赋值运算符(而不是复制赋值运算符)。移动构造函数和移动赋值运算符的实现中,只是将资源从源移
到目的地,而没有进行复制。程序清单 12.11 演示了如何使用这两项新功能对 MyString 类进行优化。

点击这里进行学习:零声学院C/C++服务器课程