深拷贝与浅拷贝解析

来源:互联网 发布:日照光华网络教育 编辑:程序博客网 时间:2024/06/05 16:35

         在未定义显示拷贝构造函数情况下,系统会调用默认的拷贝函数-----浅拷贝,它能够完成成员的一一复制,当数据成员中没有指针时,浅拷贝是可行的;

但当数据成员中有指针时,如果采用简单的浅拷贝,则两类中的两个指针将指向同一块内存,当对象块结束时,会调用2次析构函数,从而导致指针悬挂现象,这时必须采用深拷贝。

深拷贝与浅拷贝的区别在于:深拷贝会在堆内存中另外申请空间来储存数据,从而也就解决了指针悬挂问题。

总之一句话:深拷贝意味者拷贝了资源;而浅拷贝拷贝了指针,没有拷贝资源,这样使得两个指针同指向一个资源,造成同一份资源析构2次,会导致程序崩溃。

 

class MyString
{
public:
MyString();
explicit MyString(const char* pData);
MyString(const MyString& cpyDest);
~MyString();
MyString& operator=(const MyString& rString );
friend ostream& operator<<(ostream& output,const MyString& outMyStr );
const char* c_str();
private:
char* m_pData;
};
MyString::MyString()
{
m_pData=new char[1];
if(m_pData !=NULL) //判断内存是否分配成功
*m_pData='\0';
}
MyString::MyString(const char *pData)
{
if(pData ==NULL)
{
m_pData=new char[1];
if(m_pData !=NULL)
*m_pData='\0';
}
else
{
int size=strlen(pData)+1;
m_pData=new char[size];
if(m_pData !=NULL) //判断内存是否分配成功
strcpy(m_pData,pData);
}
}
MyString::MyString(const MyString& rString)
{
int size=strlen(rString.m_pData)+1;
m_pData=new char[size];
if(m_pData !=NULL) //判断内存是否分配成功
strcpy(m_pData,rString.m_pData);
}
MyString::~MyString()
{
if(m_pData !=NULL)
{
delete []m_pData;
m_pData=NULL;
}
}
MyString& MyString::operator=(const MyString& rString)
{
//检查自赋值
if(this == &rString)
return *this;

 

//释放原有的内存资源
delete []m_pData;

 

//分配新的内存资源,并拷贝内容
int size=strlen(rString.m_pData)+1;
m_pData=new char[size];
if(m_pData !=NULL) //判断内存是否分配成功
strcpy(m_pData,rString.m_pData);

 

//返回对象本身
return *this;
}
ostream& operator<<(ostream& output,const MyString& outMyStr)
{
if(outMyStr.m_pData !=NULL)
output<<outMyStr.m_pData;
return output;
}
const char* MyString::c_str()
{
return m_pData;
}

 

    位拷贝(浅拷贝),及"bitwise assignment"是指将一个对象的内存映像按位原封不动的复制给另一个对象,所谓值拷贝就是指,将原对象的值复制一份给新对象。 在用"bitwise assignment"时会直接将对象的内存映像复制给另一个对象,这样两个对象会指向同一个内存区域,当一个对象被释放后,另一个对象的指针会成为空指针。这时,就应该编写operator=和copy constructor来实现值拷贝 。


 

深拷贝和浅拷贝也可以这样理解:深拷贝就是拷贝对象的资源是源对象的资源的副本,浅拷贝就是源对象和拷贝对象共用一份资源。