右值引用
本文是基于右值引用的应用
移动语义
Move Semantics
定义
传统 C++ 通过拷贝构造函数和赋值操作符为类对象设计了拷贝/复制的概念
但为了实现对资源的移动操作,调用者必须使用先复制、再析构的方式
否则就需要自己实现移动对象的接口
试想,搬家的时候应该是把家里的东西直接搬到新家去
而不是将所有东西复制一份(重买)再放到新家、再把原来的东西全部扔掉(销毁)
右值引用解决了拷贝复制带来的资源浪费问题
移动语义是在右值引用的基础上引入的
将一个对象的内容移动到另一个对象的操作
在拷贝语义中,会调用类的拷贝构造函数或者赋值构造函数
在移动语义中,会调用类的移动构造函数
这句话的意思是当赋值的变量或者类构造参数为左值时,会调用类的那个有左值参数的构造函数;
当其为右值时,会调用类的那个有右值引用参数的重载构造函数
class TA {
int* a;
TA() {
}
TA(const TA& lvalue) {
a = new int(*lvalue.a);
}//拷贝语义
TA(const TA&& rvalue) {
a = rvalue.a;
}//移动语义
};
std::move
作用是把左值强转为右值
完美转发
Perfect Forwarding
std::forward
保持参数的引用类型
template<typename T>
void print(T& t) {
std::cout << "L" << std::endl;
}
template<typename T>
void print(T&& t) {
std::cout << "R" << std::endl;
}
template<typename T>
void testForward(T&& v) {
print(v);//始终调用左值重载的print
print(std::forward<T>(v)); //保持实参的值类型
print(std::move(v)); //始终调用右值重载的print
}
int main(int argc, char* argv[])
{
int x = 1;
testForward(x); //实参为左值
testForward(std::move(x)); //实参为右值
}
// 结果为:
// L
// L
// R
// L
// R
// R