右值引用:追要是分移动语义+完美转发。目的是减少赋值操作中的新建内存再copy的造作,直接复用右值已经申请的内存空间和里面对应的内容。
本质上是添加move constructor 和 move assignment constructor,move函数将入参类型static_cast为T&&,调用构造函数时就不会去调用copy constructor和copy assignment construcor,而是调用move的constructor。
一个 case,可以比较清楚地看到copy和move constructor的区别。注意move的constructor要加noexcept
class MyString{
public:
MyString():data(nullptr),len(0){}
MyString(char* p):len(strlen(p)){
init_data(p);
}
MyString(const MyString& p):len(p.len){
init_data(p.data);
}
MyString& operator=(const MyString& p){
if(this != &p){
if(data){
delete data;
}
len = p.len;
init_data(p.data);
}
return *this;
}
MyString(const MyString&& p) noexcept{
data = p.data;
len = p.len;
p.data = nullptr;
p.len = 0;
}
MyString& operator=(const MyString&& p) noexcept{
if(this != &p){
//直接指针指向
if(data){
delete data;
}
data = p.data;
len = p.len;
p.data = nullptr;
p.len = 0;
}
return *this;
}
private:
char* data;
size_t len;
void init_data(char* p){
data = new char[len+1];
memcpy(data,p,len);
data[len] = '/0';
}
}