右值引用:追要是分移動語義+完美轉發。目的是減少賦值操作中的新建內存再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';
}
}