几个有助于理解的小细节,
- 移动就是一个语义而已,表达“独占”的语义,或者用 Rust 的话说就是 “所有权转移”。
- 移动效率之所以 有时候 比复制快,是因为移动不需要保留源对象的值(因为所有权转移了)。
- 移动构造、移动赋值等,只是普通的函数调用,它们也是自己写的(或者编译器在合适的时候生成,或者编译器不生成),它就是一个普通的函数而已。一个类的业务怎么定义,它移动的时候就要做什么操作,这没有什么魔法。如果愿意的话,可以在移动函数里面里面做拷贝,做什么都可以,写什么它就做什么。
- C++ 中的右值是一种用来实现 move 语义的类型,而 move 的 行为 是你自己定义的。
接下来深入看看,std::move 本身没有什么神秘,实际上也并没有 move 任何东西,std::move 的实现大致是这样,
template<typename _Tp>
inline typename std::remove_reference<_Tp>::type&&
move(_Tp&& __t)
{
return static_cast<typename std::remove_reference<_Tp>::type&&>(__t);
}
可见,
- std::move 只是做了一个 cast 而已,将参数转化为 rvalue;
- 有了 rvalue,就可以触发移动语义(move semantics),让编译器调用移动构造函数或者移动赋值运算符;
- 然后执行移动操作里面自己写的代码,来执行移动操作(真正的移动操作是自己写的)。
C++的 move 根本就是骗人的,怎么能说是 move 呢?讲真,Rust 那才是真的 move。C++ 的实际操作中哪有什么 move,只有 copy。move 也仅仅是个语义而已。
以上。
网友评论