浅拷贝和深拷贝
深浅拷贝是在C++编程中,对于类对象来说,其内部存在各种类型成员变量,在拷贝过程中会出现问题。
浅拷贝在有指针的情况下,浅拷贝只是增加了一个指针指向已经存在的内存,而深拷贝就是增加一个指针并且申请一个新的内存,使这个增加的指针指向这个新的内存
char* _ptr;
int _countRef;
用_countRef
对这块空间进行监视,当一直有指针指向这块空间时不对它进行释放,当引用计数为0时再对其释放,这样就避免了刚刚出现的问题,具体代码如下:
#include <iostream>
using namespace std;
class String
{
public:
String(const char* ptr = "")
:_countRef(new int(1))
{
if (ptr == NULL)
{
_ptr = new char;
*_ptr = '\0';
}
else
{
_ptr = new char[strlen(ptr) + 1];
strcpy(_ptr, ptr);
}
*_countRef = 1;
}
String(const String & s)
:_ptr(s._ptr)
, _countRef(s._countRef)
{
++(*_countRef);
}
~String()
{
Release();
}
void Release()
{
if (--(*_countRef) == 0)
{
delete[] _ptr;
_ptr = NULL;
delete _countRef;
}
}
String& operator= (const String & s)
{
if (_ptr != s._ptr)
{
Release();//对被赋值的对象进行检查,并释放它自己的指针
_ptr = s._ptr;
_countRef = s._countRef;
++(*_countRef);
}
return *this;
}
private:
char* _ptr;
int* _countRef;
};
写时拷贝由于释放内存空间,开辟内存空间时花费时间,因此,在我们在不需要写,只是读的时候就可以不用新开辟内存空间,就用浅拷贝的方式创建对象,当我们需要写的时候才去新开辟内存空间。这种方法就是写时拷贝。在原有的引用计数的基础上加上写时拷贝:
char operator[](int index)
{
if ((*_countRef) > 1)//当引用计数大于1时开辟新空间
{
--(*_countRef);
_countRef = new int(1);
char* ptr = new char[strlen(_ptr) + 1];
strcpy(ptr, _ptr);
_ptr = ptr;//让指针指向新开辟的空间
}
return _ptr[index];
}
深拷贝是开辟一块新的空间,让新空间中的内容和原空间内容完全相同,然后让指针指向这块空间,这样在析构时不会造成对同一块内存空间释放多次的情况
#include <iostream>
#include <string>
class String
{
public:
String(const char* pStr="")
{
if (pStr == NULL)
{
_pStr = new char;
*_pStr = '\0';
}
else
{
_pStr = new char[strlen(pStr) + 1];
strcpy(_pStr, pStr);
}
}
String(const String &s)
:_pStr (_pStr = new char[strlen(s._pStr) + 1])
{
strcpy(_pStr, s._pStr);
}
String &operator=(const String &s)
{
if (this != &s)
{
char *pTemp = new char[strlen(s._pStr) + 1];
strcpy(pTemp, s._pStr);
delete[] _pStr;
_pStr = pTemp;
}
return * this ;
}
~String() //析构函数
{
if (_pStr)
{
delete[] _pStr;
_pStr = NULL;
}
}
private:
char* _pStr;
};
void FunTest()
{
String s1="1234";
String s2;
s2 = s1;
String s3(s2);
String s4 = "asahsg";
}
int main()
{
FunTest();
system("pause");
return 0;
}
合理选用合适的拷贝有利于提高代码的效率。