你怎么交换两个变量值?
这大概是每个初学编程的人都会遇到的一个问题. 你的第一反应一定是
|
|
简单来说就是当你需要交换两杯水的时候,你需要借助第三个杯子.
考虑一下它的中间开销.
- T tmp(a).你利用copy constructor重新构造了一个对象tmp,并且复制了a.
- 用 a复制了b
- 用b 复制了a
如果copy的代价很高的化…
然而有没有不复制的办法来交换两个变量的值?
有一个经典的告诫大家学会分享的萧伯纳名言:
“如果你有一个苹果,我有一个苹果,彼此交换,那么,每个人只有一个苹果;
如果你有一个思想,我有一个思想,彼此交换,我们每个人就有了两个思想,甚至多于两个思想。”
我们不是要说分享,是要说拷贝和移动的关系.如果人手一台3D打印机,可能每人也有两个苹果吧. 但你看到了,拷贝的过程,是要经历生产的开销. 即使是思想的拷贝,如果它足够复杂晦涩,那相比也要死不少脑细胞.
在C++中,有一个还比较古老的操作符叫move,就起到了这种移动的作用.
下面的一段引用来说明copy和move的关系.
Hitherto, copying has been the only means for transferring a state from one object to another (an object’s state is the collective set of its non-static data members’ values). Formally, copying causes a target object t to end up with the same state as the source s, without modifying s. For example, when you copy a string s1 to s2, the result is two identical strings with the same state as s1.
Notwithstanding the conceptual difference between copying and moving, there’s a practical difference too: Move operations tend to be faster than copying because they transfer an existing resource to a new destination, whereas copying requires the creation of a new resource from scratch. The efficiency of moving can be witnessed among the rest in functions that return objects by value.
所以交换两个值可以写作
|
|
好处是减少构造一些不必要的对象,节省了对象的空间消耗和construction 和destruction 的过程.
函数返还一个container
|
|
这是又一个例子.
这里new_values 除了在doubleValues() 里面构造了一个,在你把函数返回按结果作为右值赋给v的时候又复制了一遍.之前的new_values 作为function 的local value自然会之后被回收. 但如果直接可以把它移动出来减少拷贝开销该有多好.
move() comes to rescue again!
这里就要提到左值和右值的区别.
左值可以被看作一个有名字的value/object, 而右值是一个无名的临时value.
|
|
这个临时构造的value在你到达分号的时候就灰飞烟灭了.
那怎么做到移动而不拷贝呢?
|
|