C++移动构造函数以及move语句简单介绍(2)

#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; int len = strlen(v.value); value = new char[len + 1]; memset(value,0,len + 1); strcpy(value,v.value); } ~Str() { cout<<"调用析构函数..."<<endl; if(value != NULL) { delete[] value; value = NULL; } } }; 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; } 

结果为:

C++移动构造函数以及move语句简单介绍

这次达到了我们预想的效果,而且,用valgrind检测一下,发现,没有内存错误!

C++移动构造函数以及move语句简单介绍

所以,写拷贝构造函数的时候,切记要注意指针的浅层复制问题呀

好的,回顾了一下拷贝构造函数,下面回到移动构造函数上来。

有时候我们会遇到这样一种情况,我们用对象a初始化对象b,后对象a我们就不在使用了,但是对象a的空间还在呀(在析构之前),既然拷贝构造函数,实际上就是把a对象的内容复制一份到b中,那么为什么我们不能直接使用a的空间呢?这样就避免了新的空间的分配,大大降低了构造的成本。这就是移动构造函数设计的初衷。

下面这个图,很好地说明了拷贝构造函数和移动构造函数的区别。

C++移动构造函数以及move语句简单介绍

看明白了吗?

通俗一点的解释就是,拷贝构造函数中,对于指针,我们一定要采用深层复制,而移动构造函数中,对于指针,我们采用浅层复制

但是上面提到,指针的浅层复制是非常危险的呀。没错,确实很危险,而且通过上面的例子,我们也可以看出,浅层复制之所以危险,是因为两个指针共同指向一片内存空间,若第一个指针将其释放,另一个指针的指向就不合法了。所以我们只要避免第一个指针释放空间就可以了。避免的方法就是将第一个指针(比如a->value)置为NULL,这样在调用析构函数的时候,由于有判断是否为NULL的语句,所以析构a的时候并不会回收a->value指向的空间(同时也是b->value指向的空间)

所以我们可以把上面的拷贝构造函数的代码修改一下:

#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; 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; } 

结果为:

C++移动构造函数以及move语句简单介绍

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/a73b3ca2a89113c6f8c928ce2618a235.html