类(七)《一谈类的更深与番外》·(四)移动

5.左值与右值

移动是指将右值移动,因此,我们首先要知道什么是左值,什么是右值。

1.变量是左值

由于变量是左值,所以我们不能将一个右值引用绑定到左值上。参考以下例子:

int i=5;//左值
int& r=i;//左值引用
int&& o=i;//错误,i是左值
2.表达式是右值

由于表达式是右值,所以我们可以将一个右值引用绑定到左值上。参考以下例子:

int i=4;
int&& r=i*16;//这是右值!!!

注意:右值引用也是左值!!! 由于变量都是左值,所以右值引用也是左值!!!
以下代码是错误的!!!

int i=6;
int&& o=i*42;
int&& r=o;//错误,o是左值!!!

6.std::move函数

如5.2章所说,那么我们也就没有办法用一个右值引用去给另一个右值赋值,那么每次都要重新写一个表达式,这样非常麻烦。我们可以使用标准库std::move() 函数就可以简便许多。它定义在标准库utility中。所以上图可以这么改:

int i=9;
int&& p=i+68;
int&& q=std::move(p);

6.1移动构造函数

既然有可能使用右值引用,那么我们还要写一个移动构造函数。形式如下:

class A{
//...
public:
    A(){ }
    A(const A&);
    A(A&& mem){ std::move(mem); }
    //...
};

6.2std::move后…

当我们移动一个对象之后,这个对象就成了移后源对象。一个移后源对象必须是可析构的。所以,我们要将移动后的对象进入可析构状态
举个例子,假设我们的pointer类有一个指针,那么我们应该这么写它的移动构造函数:

class pointer{
//...
private:
    char* point;
    //....
public:
    //...
    pointer(pointer&& mem):point(nullptr){ std::move(mem); }
    //正确,析构point是安全的
    //...
};

移动对象后,我们只能对它赋值或析构

如有错误,请在评论区提出,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值