//存储资源引用计数的表,使用单例模式因为模板在类型推导的时候
//会因为类型的不同从而产生不同的表,对于引用计数来说会产生错误
//因为这两张表应该在同一张表中,在调试中遇到的这个问题
class ResTable
{
public:
typedef map<void*, int>::iterator iterator;
/*
快加载:没调用getInstance函数,对象实例就生成了
慢加载:第一次调用getInstance函数,对象实例才生成
*/
static ResTable& getInstance()
{
return mResTable;
}
//增加ptr资源的引用计数
void addRef(void *ptr)
{
//_resMap[ptr]++;
iterator it = _resMap.find(ptr);
if(it == _resMap.end())
{
_resMap.insert(make_pair(ptr, 1));
cout<<"add res:"<<ptr<<" cnt:"<<1<<endl;
}
else
{
it->second++;
cout<<"add res:"<<ptr<<" cnt:"<<it->second<<endl;
}
}
//删除ptr资源的引用计数
void delRef(void *ptr)
{
iterator it = _resMap.find(ptr);
if(it != _resMap.end())
{
it->second--;
cout<<"del res:"<<ptr<<" cnt:"<<it->second<<endl;
if(it->second == 0)
_resMap.erase(ptr);
}
}
//获取ptr资源的引用计数
int getRef(void *ptr)
{
iterator it = _resMap.find(ptr);
if(it != _resMap.end())
{
return it->second;
}
return 0;
}
private:
map<void*, int> _resMap;
static ResTable mResTable;
ResTable(){}
};
ResTable ResTable::mResTable;
template<typename Ty>
class CSmartPtr
{
public:
CSmartPtr(Ty *ptr = NULL)
:mptr(ptr)
{
if(mptr != NULL)
{
addRef();
}
}
CSmartPtr(const CSmartPtr<Ty> &src)
:mptr(src.mptr)
{
if(mptr != NULL)
{
addRef();
}
}
CSmartPtr<Ty>& operator=(const CSmartPtr<Ty> &src)
{
if(this == &src)
return *this;
delRef();
if(getRef() == 0)
{
delete mptr;
}
mptr = src.mptr;
addRef();
return *this;
}
~CSmartPtr()
{
delRef();
if(getRef() == 0)
{
delete mptr;
mptr = NULL;
}
}
Ty& operator*(){return *mptr;}
Ty* operator->(){return mptr;}
void addRef(){_table.addRef(mptr);}
void delRef(){_table.delRef(mptr);}
int getRef(){return _table.getRef(mptr);}
private:
Ty *mptr;
static ResTable &_table;
};
template<typename T>
ResTable& CSmartPtr<T>::_table = ResTable::getInstance();
int main()
{
int *p = new int;
CSmartPtr<int> p1(p);
CSmartPtr<char> p2((char*)p);
// CSmartPtr<int> p1(new int);
// *p p->
// *p1 = 100;
// cout<<*p1<<endl;
// CSmartPtr<int> p2(p1);
// *p2 = 200;
// cout<<*p1<<endl;
// CSmartPtr<int> p3(new int);
// p2 = p3;
// p3 = p1;
// CSmartPtr<Test> p2(new Test);
// p2.operator->(func())
// (p2.operator->())->func();
// p2->func();
return 0;
}
自己实现一个带引用计数的智能指针,根据源码
最新推荐文章于 2021-09-02 11:23:59 发布