采用引用计数器来记录浅拷贝的次数 合理释放资源
当写新的内容时 使用NEW关键字进行深拷贝操作 并将之前的资源释放 且 引用计数-1
#include<iostream>
#include<Cstring>
using namespace std;
struct Refvalue{
Refvalue(const char* pszName);
~Refvalue()
{
if(m_pszName!=nullptr)
{
delete m_pszName;
m_pszName=nullptr;
}
}
void AddRef(){m_nCount++;}
void Release(){
if(--m_nCount==0) delete this;
}
char* m_pszName;
int m_nCount;
};
Refvalue::Refvalue(const char* pszName)
{
m_pszName=new char[256];//此为学生名字
strcpy(m_pszName,pszName);
m_nCount=1;//初始引用计数为1
}//计数器与类的参数进行绑定
class Cstudent{
private: Refvalue* m_pValue;
public:
Cstudent(const char* pszName);
Cstudent(Cstudent & obj);//构造函数
~Cstudent(){ release();}
Cstudent & operator=(Cstudent& obj);//赋值运算重载函数
void release();
void setname(const char* pszName);//设置名字
void show(){
if(m_pValue->m_nCount>0)
cout<<hex<<(int &)m_pValue<<m_pValue->m_pszName<<endl;
return;
}
};
Cstudent::Cstudent(const char* pszName)//初始化
{
m_pValue= new Refvalue(pszName);
}
Cstudent::Cstudent(Cstudent &obj)//浅拷贝
{
m_pValue=obj.m_pValue;
m_pValue->AddRef();
}
void Cstudent::setname(const char* pszName)//设置名字(写时拷贝)
{
m_pValue->Release();//原有资源释放
m_pValue=new Refvalue(pszName);
}
void Cstudent::release()
{
m_pValue->Release();
}
Cstudent& Cstudent::operator=(Cstudent& obj)
{
if(obj.m_pValue==m_pValue) return *this;
m_pValue->Release();//清除原有的NAME
m_pValue=obj.m_pValue;//赋值
m_pValue->AddRef();//count++ : 引用计数+1
return *this;
}//此外还可以使用赋值重载函数实现深拷贝 结合NEW关键字 和STRCPY方法
//ClassA& operator=(const ClassA& cls)
//{
// // 避免自赋值
// if (this != &cls)
// {
// // 避免内存泄露
// if (pszTestStr != NULL)
// {
// delete pszTestStr;
// pszTestStr = NULL;
// }
// pszTestStr = new char[strlen(cls.pszTestStr) + 1];
// strncpy(pszTestStr, cls.pszTestStr, strlen(cls.pszTestStr) + 1);
// }
//
// return *this;
int main()
{
Cstudent s2("li si");
Cstudent s3=s2;//浅拷贝赋值
s2.show();//count=2 nmae="li si"
s3.show();// count=2 nmae="li si"
s2.setname("li si2");//写时拷贝
s2.show();//count=1 nmae="li si2"
s3.show();//count=1 nmae="li si"
return 0;
}