在学习string的时候才开始正式认识深浅拷贝,现在总结下,方便以后学习。
浅拷贝
浅拷贝就是 对内存地址的复制,使目标对象指针和源对象指针指向同一块地址空间。
例如:
char* p = new char[10];
char* ptr = p;
浅拷贝是对对象的简单拷贝,让几个指针都指向同一块地址空间,在释放这段空间的时候会产生“对已释放的空间再次释放”,导致程序中断。
实现string遇到的浅拷贝:
如果在string中没有显式给出拷贝构造函数,那么系统会默认合成一个拷贝构造函数,如下:
String( String& s)
{
_pStr = s._pStr;
}
这样就导致了两个对象共用一块内存,在对象消亡调用析构函数时,会对同一块空间释放多次,程序就中断了。这样就会提到深拷贝。
深拷贝
深拷贝拷贝的是对象的具体内容,而内存地址是自主分配的,拷贝结束之后,两个对象虽然存的值是相同的,但是内存地址不一样,两个对象也互不影响,互不干涉。
在string中,解决上述浅拷贝问题的方法:
<span style="color:#3333ff;"> String(const String& s)
:_str(new char[strlen(s._str) + 1])//自己申请了内存
{
strcpy(_str, s._str); //值拷贝
}</span>
其实在string的赋值运算符重载也同样会遇到这样的问题,如同上面一样,就能很好的解决。
总结:
在有指针的情况下,浅拷贝只是增加了一个指针指向已经存在的内存,而深拷贝就是增加一个指针并且申请一个新的内存,使这个增加的指针指向这个新的内存,采用深拷贝的情况下,释放内存的时候就不会出现在浅拷贝时重复释放同一内存的错误!