std::move的原理
std::move的定义:
这里,T&&是通用引用,需要注意和右值引用(比如int&&)区分。通过move定义可以看出,move并没有”移动“什么内容,只是将传入的值转换为右值,此外没有其他动作。std::move+移动构造函数或者移动赋值运算符,才能充分起到减少不必要拷贝的意义。
std::move的使用场景
在之前的项目中看到有的同事到处使用std::move,好像觉得使用了std::move就能移动资源,提升性能一样,在我看来,std::move主要使用在以下场景:
- 使用前提:1 定义的类使用了资源并定义了移动构造函数和移动赋值运算符,2 该变量即将不再使用
- 使用场景
RValue a, b;
//对a,b坐一系列操作之后,不再使用a,b,但需要保存到智能指针或者容器之中
unique_ptr<RValue> up(new RValue(std::move(a)));
vector<RValue*> vr;
vr.push_back(new RValue(std::move(b)));
//临时容器中保存的大量的元素需要复制到目标容器之中
vector<RValue> vrs_temp;
vrs_temp.push_back(RValue());
vrs_temp.push_back(RValue());
vrs_temp.push_back(RValue());
vector<RValue> vrs(std::move(vrs_temp));
RValue c;
put(std::move(c));
View Code
- 在没有右值引用之前,为了使用临时变量,通常定义const的左值引用,比如const string&,在有了右值引用之后,为了使用右值语义,不要把参数定义为常量左值引用,否则,传递右值时调用的时拷贝构造函数
void put(const RValue& c){
cout<<"----------"<<endl;
unique_ptr<RValue> up(new RValue(std::move(c)));
cout<<"----------"<<endl;
}
RValue c;
put(std::move(c));
g++ move.cpp -std=c++11 -o move
./move
----------
& RValue
----------
View Code
不使用左值常量引用:
void put(RValue c){
cout<<"----------"<<endl;
unique_ptr<RValue> up(new RValue(std::move(c)));
cout<<"----------"<<endl;
}
RValue c;
put(std::move(c));
g++ move.cpp -std=c++11 -o move
./move
&& RValue
----------
&& RValue
----------
View Code
这是因为,根据通用引用的定义,std::move(c)过程中,模板参数被推倒为const RValue&,因此,调用拷贝构造函数。
- unique_ptr
形参为unique_ptr u2,而后实参为std::move(unique_ptr u1),这样会将原本u1的内存传递给u2,避免了传递拷贝。例如
void fun(std::unique_ptr u2)
{
}
unique_ptr<cls> u1;
fun(std::move(u1));
View Code
总结
通过简绍右值和右值引用以及std::move和移动构造函数,总结右值引用,移动构造函数和移动赋值运算符和std::move的用法和注意事项。
转自:
https://zhuanlan.zhihu.com/p/94588204
原文链接: https://www.cnblogs.com/calla/p/14741830.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/210280
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!