在看c++ primer的时候,了解到了一个c++11的新标准,故记录一下自己的见解。
std::move(对象移动)
需求
首先,这是C++为了避免copy的一种新做法。
- 正如我们之前了解到的,程序运行过程中很多情况下会发生对象拷贝,但如果在某些特殊情况下,object被copy后就开始销毁,那么如果使用对象move就能大幅度提高性能。
- 另一个原因则是,像IO类或者unique_ptr类是不允许共享资源的,因此这些类不可以被copy。由此引发的一个是,在旧标准里面,容器只能保存可以被拷贝的类。而新标准里,可以保存不被拷贝的类,只要该类能被移动即可。
含义
举个例子,通过copy constructor,容器vector能将内部指向数据的指针copy起来,原指针则使其为null,这样就避免了对数据内容的copy。
简单说明一下,copy constructor就是分配新的资源,而move constructor则是接管了原来的资源,获得使用了原来资源的权利。
用c++ primer的说法是“窃取”了资源
rvalue reference(右值引用)
需求
为了支持move操作,c++11新标准引进了一个新的引用类型——rvalue reference。
含义
顾名思义,右值引用则是绑定到右值得引用,这其中就涉及到了一个非常有用的性质——右值引用只能绑定到一个将要销毁的对象。只有这样,我们才能将原对象资源move到新的对象当中去。
- 我们把常规的引用叫做左值引用,通过&来取得;不能将其绑定到需要转换的表达式,字面常量和返回右值得表达式
- 而通过&&则可以获得右值引用;同理,右值引用则有着相反的性质,不能将右值应用绑定到左值上;
举个例子:
1 | int i = 42; |
注意一下,我们可以将一个const的左值引用或右值引用绑定到右值表达式上
总结一下,左值是持久的,右值是短暂的;因为只有将要被销毁的对象,我们才可以从绑定到右值引用的对象上获取其状态。
使用
这里先借用一下stackoverflow某位答主的话:
std::move()is a cast that produces an rvalue-reference to an object, to enable moving from it
为了我们可以将右值引用直接绑定到左值上,我们可以利用std::move这个标准库函数来获得绑定到左值上的右值引用。该函数定义在头文件utility中。
1 | int &&rr2 = std::move(rr1); // ok |
- tips:由于move的名字冲突比其他标准库函数要频繁得多,因此最好加上限定语,不适用using。