带引用计数的智能指针思想:
1.构造函数:新构造一个对象,初始化引用计数为1;
2.析构函数:首先给引用计数-1,然后判断引用计数是否为0,如果为0,直接delete掉;
3.赋值运算符的重载函数:判断自赋值,给引用计数-1如果为0(检查原本占有的资源是否被其他对象占用,如果没有就直接释放吧),就释放原来资源;否则就讲src的外部资源赋值过来,然后引用计数+1.
4,拷贝构造函数:判断mptr是否为空,如果不为空,就给引用计数+1,给指针赋值。
实现一个带引用计数的智能指针:
//实现一个带引用计数的智能指针:
#include<unordered_map>
#include<iostream>
using namespace std;
//引用计数类
class ReferenceCount
{
public:
//给ptr指向的资源增加引用计数
void incRef(void *ptr){
refMap[ptr]++;
}
//给ptr指向的资源减少引用计数
int decRef(void *ptr){
unordered_map <void*, int>::iterator it = refMap.find(ptr);
if (it == refMap.end()){
return 0;
}else{
int ret = --(it->second);
if (it->second == 0){
refMap.erase(it);
}
return ret;
}
}
private:
//map的key表示资源地址, value表示资源的引用计数
unordered_map <void*, int> refMap;
};
//智能指针
template <typename T>
class CSmartPtr
{
public:
CSmartPtr(T *ptr = NULL)
:mptr(ptr){
if (mptr != NULL){
incRef();
}
}
CSmartPtr(const CSmartPtr &src)
:mptr(src.mptr){
if (mptr != NULL){
incRef();
}
}
CSmartPtr& operator=(const CSmartPtr &src){
if (this == &src)
return *this;
if (decRef() == 0){
delete mptr;
mptr = NULL;
}
mptr = src.mptr;
if (mptr != NULL){
incRef();
}
return *this;
}
~CSmartPtr(){
if (decRef() == 0){
delete mptr;
mptr = NULL;
}
}
T& operator*(){
return *mptr;
}
const T& operator*()const{
return *mptr;
}
T* operator->(){
return mptr;
}
T* operator->()const{
return mptr;
}
private:
T *mptr;
//专门供智能指针,查看当前它所引用的资源的引用计数
static ReferenceCount refCnt;
void incRef(){ refCnt.incRef(mptr); }
int decRef(){ return refCnt.decRef(mptr); }
};
template<typename T>
ReferenceCount CSmartPtr<T>::refCnt; //类外初始化
使用:
int main(){
CSmartPtr<int> ptr1(new int);
*ptr1 = 100;
CSmartPtr<int> ptr2 = ptr1;
CSmartPtr<int> ptr3 = ptr1;
CSmartPtr<int> ptr4(ptr2);
std::cout<<*ptr1<<std::endl;
std::cout<<*ptr2<<std::endl;
std::cout<<*ptr3<<std::endl;
std::cout<<*ptr4<<std::endl;
return 0;
}
执行结果:
100
100
100
100