首先,看一下移动构造函数的使用,move()使用实例:
//移动构造函数, move()的使用
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <vector>
using namespace std;
int main()
{
string st = "I love xing";
vector<string> vc ;
vc.push_back(move(st));
cout<<vc[0]<<endl; //拷贝后string
if(!st.empty()) //源string
cout<<st<<endl;
return 0;
}
输出:
I love xing
再来看一下通常我们使用的拷贝构造函数的使用实例:
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <vector>
using namespace std;
int main()
{
string st = "I love xing";
vector<string> vc ;
vc.push_back(st);
cout<<vc[0]<<endl; //拷贝后的string
if(!st.empty())
cout<<st<<endl; //源string
return 0;
}
输出:
I love xing
I love xing
这两个小程序唯一的不同是调用vc.push_back()将字符串插入到容器中去时,第一段代码使用了move语句,而第二段代码没有使用move语句。输出的结果差异也很明显,第一段代码中,原来的字符串st已经为空,而第二段代码中,原来的字符串st的内容没有变化。
move():是一种浅层拷贝,当用a初始化b后,a不再需要时,最好是初始化完成后就将a析构,使用move最优。
如果说,我们用a初始化了b后,仍要对a进行操作,用这种浅层复制的方法就不合适了。所以C++引入了移动构造函数,专门处理这种,用a初始化b后,就将a析构的情况。这种操作的好处是:将a对象的内容复制一份到b中之后,b直接使用a的内存空间,这样就避免了新的空间的分配,大大降低了构造的成本。这就是移动构造函数设计的初衷。
注:析构是不会释放内存空间的。
移动构造函数的使用,注意调用拷贝构造函数时的重要一句: v.value = NULL;
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <vector>
using namespace std;
class Str{
public:
char *value;
Str(char s[])
{
cout<<"调用构造函数..."<<endl;
int len = strlen(s);
value = new char[len + 1];
memset(value,0,len + 1);
strcpy(value,s);
}
Str(Str &v)
{
cout<<"调用拷贝构造函数..."<<endl;
this->value = v.value;
//将源变量置为NULL,使其调用析构时不释放内存源数据内存,因为拷贝前后使用同一块内存空间
v.value = NULL;
}
~Str()
{
cout<<"调用析构函数..."<<endl;
if(value != NULL)
delete[] value;
}
};
int main()
{
char s[] = "I love BIT";
Str *a = new Str(s);
Str *b = new Str(*a);
delete a;
cout<<"b对象中的字符串为:"<<b->value<<endl;
delete b;
return 0;
}
本人只介绍move语句的使用,及移动构造函数的好处,关于拷贝构造函数、深拷贝,浅拷贝的详细说明请参考:https://www.cnblogs.com/qingergege/p/7607089.html