右值引用
左值:可以取地址、有名字的
右值:不能取地址、没名字的
传统的C++引用称为左值引用,使得标志符关联到左值。
C++11新增了右值引用,使用&&表示。
引入右值引用的主要目的之一是实现移动语义。
移动语义
在复制对象时,实现对象的移动而非拷贝。
通过移动构造函数、移动赋值运算符实现:函数的参数为右值引用,函数内部并非深度复制,而是夺取所有权。在将所有权转移给新对象的过程中,移动构造函数可能修改其实参,这意味着右值引用参数不应是const。
移动构造函数
对一个类:
class Useless
{
private:
int n;
char * pc;
static int ct;
void ShowObject() const;
public:
Useless();
Useless(int k,char ch);
Useless(const Useless & f); //复制构造函数
Useless(Useless && f); //移动构造函数
~Useless();
};
复制构造函数:
Useless::Useless(const Useless & f): n(f.n)
{
++ct;
pc = new char[n];
for(int i=0;i<n;i++)
pc[i]=f.pc[i];
}
移动构造函数:
Useless::Useless(Useless && f): n(f.n)
{
++ct;
pc=f.pc;
f.pc=nullptr;
f.n=0;
}
它让pc指向现有的数据,以获取这些数据的所有权。此时,pc和f.pc指向相同的数据,调用析构函数时将带来麻烦,因为程序不能对同一个地址调用delete[]两次。为避免这个问题,改构造函数随后将原来的指针设置为空指针。由于修改了f对象,这要求不能在参数声明中使用const。