右值引用和对象移动

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wk_bjut_edu_cn/article/details/82082967

右值引用

概念

为了支持移动操作,C++11引入了一种新的引用类型-右值引用。就是必须绑定到右值的引用。我们通过&&而不是&来获得右值引用。右值引用只能绑定到一个将要销毁的对象。

由于右值引用只能绑定到临时对象,我们得知:

所引用的对象将要被销毁

该对象没有其他用户

这两个特性意味着:使用右值引用的代码可以自身自由的接管所引用的对象的资源。

变量可以看作只有一个运算对象而没有运算符的表达式。

	int i = 23;
	int &&j = i;//错误:不能将一个右值引用绑定到一个左值上
	int &&k = i * 3;//正确,i*3是一个右值

标准库move函数

虽然不能将一个右值引用直接绑定到一个左值上,但可以通过调用一个名为move的新标准库函数来获得绑定到左值上的右值引用。

int i=6;
int &&l=std::move(i);

对象移动

提出

在很多情况下都会发生对象拷贝,比如利用reallocate重新分配内存的过程,在其中某些情况下,对象拷贝后就立即被销毁了。在这些情况下,移动而非拷贝对象会大幅度提升性能。

移动构造函数和移动赋值运算符

移动构造函数,参数是右值引用

StrVec::StrVec(StrVec &&s) noexcept                 //noexcept指名不抛出异常
:elements(s.elements), first_free(s.first_free),cap(s.cap)
{
            s.elements = s.first_free = s.cap = nullptr;  //销毁地动源后的对象
}

与拷贝构造函数不同,移动构造函数不分配任何新内存:它接管给定的StrVec中的内存。在接管内存后,它将给定对象中的指针都置为nullptr。

合成的移动操作

与处理拷贝构造函数和拷贝赋值运算符一样,编译器也会合成移动构造函数和移动赋值运算符。但是,合成移动构造的条件与合成拷贝操作的条件大不相同。

扫描二维码关注公众号,回复: 3307311 查看本文章

只有当一个类没有定义任何自己版本的拷贝控制成员(拷贝构造函数、拷贝赋值运算符、析构函数),且它的所有数据成员都能移动构造或移动赋值时,编译器才会为它合成移动构造函数或移动赋值运算符。

如果一个类定义了一个移动构造函数或一个移动赋值运算符,则该类的合成拷贝构造函数和拷贝赋值运算符被定义为删除的。

右值引用和成员函数

除了构造函数和赋值运算符之外,成员函数也可以同时提供拷贝版本和移动版本。例如:

void push_back(const X&);    //拷贝:绑定到任意类型的X
void push_back(X&&);    //移动:只能绑定到类型X的可修改的右值

猜你喜欢

转载自blog.csdn.net/wk_bjut_edu_cn/article/details/82082967
今日推荐