右值引用,移动构造,移动赋值
这里就不说概念了,只是对用法的探究。
#include <functional>
#include <iostream>
#include <string.h>
#include <string>
using namespace std;
class MyPair
{
public:
MyPair()
{
a = 'a';
b = new int(0);
cout << "constructor" << endl;
}
MyPair(const MyPair& myPair)
{
this->b = new int(*myPair.b);
this->a = myPair.a;
cout << "copy" << endl;
}
MyPair(const MyPair&& myPair)
{
this->b = new int(*myPair.b);
this->a = myPair.a;
cout << "move copy" << endl;
}
MyPair& operator=(const MyPair& myPair)
{
this->b = new int(*myPair.b);
this->a = myPair.a;
cout << "operator=" << endl;
return *this;
}
MyPair& operator=(const MyPair&& myPair)
{
this->b = new int(*myPair.b);
this->a = myPair.a;
cout << "move operator=" << endl;
return *this;
}
~MyPair()
{
delete b;
cout << "disconstructor" << endl;
}
char a;
int* b;
MyPair get()
{
MyPair myPair;
return myPair;
}
};
int main()
{
MyPair myPair1;
MyPair myPair2 = std::move(MyPair());
myPair2.a = 'd';
*myPair2.b = 10;
cout << myPair1.a << endl;
cout << myPair2.a << endl;
}
这里在myPair2 声明的时候通过std::move(MyPair())赋值和赋值构造函数一样,但是这里不会调用拷贝构造函数,因为std::move会返回一个右值引用,所以这里会调用移动拷贝构造函数。
int main()
{
MyPair myPair1;
MyPair myPair2;
myPair2 = std::move(MyPair());
myPair2.a = 'd';
*myPair2.b = 10;
cout << myPair1.a << endl;
cout << myPair2.a << endl;
}
这里不是在定义时候用一个对象给另一个对象赋值就会调用移动赋值函数。
#include <functional>
#include <iostream>
#include <string.h>
#include <string>
using namespace std;
class MyPair
{
public:
MyPair()
{
a = 'a';
b = new int(0);
cout << "constructor" << endl;
}
MyPair(const MyPair& myPair)
{
this->b = new int(*myPair.b);
this->a = myPair.a;
cout << "copy" << endl;
}
// MyPair(const MyPair&& myPair)
// {
// this->b = new int(*myPair.b);
// this->a = myPair.a;
// cout << "move copy" << endl;
// }
MyPair& operator=(const MyPair& myPair)
{
this->b = new int(*myPair.b);
this->a = myPair.a;
cout << "operator=" << endl;
return *this;
}
// MyPair& operator=(const MyPair&& myPair)
// {
// this->b = new int(*myPair.b);
// this->a = myPair.a;
// cout << "move operator=" << endl;
// return *this;
// }
~MyPair()
{
delete b;
cout << "disconstructor" << endl;
}
char a;
int* b;
MyPair get()
{
MyPair myPair;
return myPair;
}
};
int main()
{
MyPair myPair1;
MyPair myPair2;
myPair2 = std::move(MyPair());
myPair2.a = 'd';
*myPair2.b = 10;
cout << myPair1.a << endl;
cout << myPair2.a << endl;
}
int main()
{
MyPair myPair1;
MyPair myPair2 = std::move(MyPair());
myPair2.a = 'd';
*myPair2.b = 10;
cout << myPair1.a << endl;
cout << myPair2.a << endl;
}
假如现在如果没有移动拷贝构造和移动赋值函数会怎么样呢?
就会调用拷贝构造函数和赋值构造函数,而这两个我们都很清楚,编译器默认会帮我们生成,并且都是浅拷贝。
#include <functional>
#include <iostream>
#include <string.h>
#include <string>
using namespace std;
class MyPair
{
public:
MyPair()
{
a = 'a';
b = new int(0);
cout << "constructor" << endl;
}
MyPair(const MyPair& myPair)
{
this->b = new int(*myPair.b);
this->a = myPair.a;
cout << "copy" << endl;
}
// MyPair(const MyPair&& myPair)
// {
// this->b = new int(*myPair.b);
// this->a = myPair.a;
// cout << "move copy" << endl;
// }
MyPair& operator=(const MyPair& myPair)
{
this->b = new int(*myPair.b);
this->a = myPair.a;
cout << "operator=" << endl;
return *this;
}
// MyPair& operator=(const MyPair&& myPair)
// {
// this->b = new int(*myPair.b);
// this->a = myPair.a;
// cout << "move operator=" << endl;
// return *this;
// }
~MyPair()
{
cout << "disconstructor" << endl;
}
char a;
int* b;
MyPair get()
{
MyPair myPair;
return myPair;
}
};
int main()
{
MyPair myPair1;
MyPair&& myPair2 = std::move(myPair1);
myPair2.a = 'd';
*myPair2.b = 10;
cout << myPair1.a << endl;
cout << myPair2.a << endl;
cout << *myPair1.b << endl;
cout << *myPair2.b << endl;
}
现在假如是这种情况就可以完全看做是操作同一块内存。
然而一般右值引用是解决这样一个问题的:
#include <functional>
#include <iostream>
#include <string.h>
#include <string>
using namespace std;
class MyPair
{
public:
MyPair()
{
a = 'a';
b = new int(0);
cout << "constructor" << endl;
}
MyPair(const MyPair& myPair)
{
this->b = new int(*myPair.b);
this->a = myPair.a;
cout << "copy" << endl;
}
MyPair(MyPair&& myPair)
{
this->b = myPair.b;
myPair.b = nullptr;
this->a = myPair.a;
cout << "move copy" << endl;
}
MyPair& operator=(const MyPair& myPair)
{
this->b = new int(*myPair.b);
this->a = myPair.a;
cout << "operator=" << endl;
return *this;
}
// MyPair& operator=(const MyPair&& myPair)
// {
// this->b = new int(*myPair.b);
// this->a = myPair.a;
// cout << "move operator=" << endl;
// return *this;
// }
~MyPair()
{
if (b != nullptr)
{
delete b;
}
cout << "disconstructor" << endl;
}
char a;
int* b;
MyPair get()
{
MyPair myPair;
return myPair;
}
};
int main()
{
MyPair myPair2 = std::move(MyPair());
myPair2.a = 'd';
*myPair2.b = 10;
cout << myPair2.a << endl;
cout << *myPair2.b << endl;
}
去偷取临时对象的内存,不用再去分配内存,提高对象拷贝的效率。偷取过程可以用下图表示。