前面已经对AutoPtr 、ScopedPtr / ScopedPtrArray 已认识了不少,现在就直接把另一种智能指针SharePtr/SharePtrArray模拟实现出来。
首先介绍这个智能指针的作用:
SharePtr很明显,从单词的意思 就很明白了,"共享"。
基本思想:利用引用计数实现多个对象共同管理一块空间
过程:创建一个_pCount指针变量,指向一块空间,对其计数,当只有一个指针指向空间时再释放资源,实现对其管理。初衷也是解决多个指针指向同一块空间释放多次会崩溃。
疑问:为什么不使用static整形变量?
这里不用static的整型的pCount在于,若有多个指针指向第一块空间,多个指针指向第二块空间,……,当改变一块空间的指向,该块空间的引用计数发生变化了,static的pCount会导致其他空间的引用计数也发生变化。
SharePtr(管理单个对象)
template<class T>
class SharedPtr
{
public:
SharedPtr(T* ptr = NULL) //构造
:_ptr(ptr)
,_pCount(new int(1))
{
cout << "SharedPtr" << endl;
}
~SharedPtr() //析构函数
{
if ((--*_pCount) == 0
&& _ptr != NULL)
{
delete _ptr;
_ptr = NULL;
delete _pCount;
_pCount = NULL;
}
}
SharedPtr<T>(SharedPtr<T>& sp) //拷贝构造
: _ptr(sp._ptr)
, _pCount(sp._pCount)
{
++(*_pCount);
}
SharedPtr<T>& operator=(SharedPtr<T>& sp)//赋值运算符重载
{
if (this != &sp)
{
if (_ptr != NULL)
{
delete _ptr;
}
_ptr = sp._ptr;
++(*_pCount);
}
return *this;
}
T* operator->()
{
return this->_ptr;
}
T& operator*()
{
return *_ptr;
}
private:
T* _ptr;
int* _pCount;
};
//测试函数
int main()
{
SharedPtr<int> sp1(new int(10) );
SharedPtr<int> sp2(sp1);
SharedPtr<int> sp3 = sp2;
//SharedPtr<int> sp4(new int(5));
//SharedPtr<int> sp5(sp4);
return 0;
}
ScopedPtrArray(管理数组)
template<typename T>
class SharePtrArray
{
public:
SharePtrArray(T* pArr = NULL)
:_pArr(pArr)
, _pCount(new int(1))
{}
~SharePtrArray()
{
if (--(*_pCount) == 0
&& _pArr != NULL)
{
delete[] _pArr;
_pArr = NULL;
delete _pCount;
_pCount = NULL;
}
}
SharePtrArray<T>(SharePtrArray<T>& pa)
: _pArr(pa._pArr)
, _pCount(pa._pCount)
{
++(*_pCount);
}
SharePtrArray<T>& operator=(SharePtrArray<T> & pa)
{
if (this != &pa)
{
if (_pArr != NULL)
{
delete[] _pArr;
}
_pArr = pa._pArr;
*_pCount = ++*(pa._pCount);
}
return *this;
}
T& operator[](size_t index)
{
return _pArr[index];
}
private:
T* _pArr;
int* _pCount;
};
//测试
int main()
{
int *p = new int[5];
SharePtrArray<int> pa(p);
SharePtrArray<int> pa1(pa);
SharePtrArray<int> pa2;
pa2 = pa1;
pa2[1] = 5;
int ret = pa2[1] ;
return 0;
}