最早的智能指针在Boost库里面,Boost库是为C++标准库提供扩展的一些C++程序的总称,由Boost社区组织开发维护。
#define _CRT_SECURE_NO_WARNINGS 1
#include
using namespace std;
template
class SharpedPtr
{
public:
SharpedPtr(T* ptr = 0)//构造函数
:_ptr(ptr)
, _pCount(NULL)
{
if (ptr)
{
_pCount = new int(1);
}
}
SharpedPtr(const SharpedPtr& ap)//拷贝构造
:_ptr(ap._ptr)
, _pCount(ap._pCount)
{
if (_ptr)
{
++UseCount();
}
}
//ap1 = ap2;赋值运算符重载
//①ap1内部封装的指针为空
//②ap1独占一块空间
//③ap1与其他对象共享一块空间
SharpedPtr& operator=(const SharpedPtr& ap)
{
if (this != &ap)
{
if (_ptr)
{
Release();
}
//ap1与其他对象共享一块空间
_ptr = ap._ptr;
_pCount = ap._pCount;
++UseCount();
}
return *this;
}
//析构函数
~SharpedPtr()
{
Release();
}
//检查引用计数并释放空间
void Release()
{
if (0 == --UseCount())
{
delete _pCount;
_pCount = NULL;
delete _ptr;
_ptr = NULL;
}
}
//获取引用计数
int& UseCount()
{
return *_pCount;
}
//为了使其更像一个指针,所完成的基本操作
T* operator->()
{
return _ptr;
}
T& operator*()
{
return *_ptr;
}
private:
T* _ptr;
int* _pCount;
};
void TestSharpedPtr()
{
SharpedPtr ap1(new int(10));
SharpedPtr ap2(new int(20));
SharpedPtr ap3(ap1);
SharpedPtr ap4;
ap4 = ap1;
*ap1 = 1;
*ap2 = 2;
*ap3 = 3;
*ap4 = 4;
}
int main()
{
TestSharpedPtr();
return 0;
}
shared_ptr 本身不是 100% 线程安全的。它的引用计数本身是安全且无锁的,但对象的读写则不是,因为 shared_ptr 有两个数据成员,读写操作不能原子化。shared_ptr 的线程安全级别和内建类型、标准库容器、string 一样,即:
#define _CRT_SECURE_NO_WARNINGS 1
#include
using namespace std;
//为解决文件指针
struct Fclose
{
void operator()(FILE*& fp)
{
cout<< "Fclose()" << endl;
fclose(fp);
fp = NULL;
}
};
//为解决malloc开辟的空间
template
struct Free
{
void operator()(T*& p)
{
free(p);
p = NULL;
}
};
//一般情况下(使用new动态开辟的空间)
template
class Delete
{
public :
void operator()(T*& p)
{
delete p;
p = NULL;
}
};
template >
class SharedPtr
{
public :
SharedPtr(T* ptr = 0)//构造函数
:_ptr(ptr)
,_pCount(NULL)
{
if (_ptr)
{
_pCount = new int(1);
}
}
SharedPtr(const SharedPtr& sp)//拷贝构造函数
:_ptr(sp._ptr)
, _pCount(sp._pCount)
{
if (_ptr)
{
++GetRef();
}
}
//sp1 = sp2
SharedPtr& operator=(const SharedPtr& sp)
{
//可有三种情况:①sp1._ptr = NULL ②sp1的引用计数为1 ③sp1的引用计数大于1
if (this != &sp)
{
Release();
_ptr = sp._ptr;
_pCount = sp._pCount;
++GetRef();
}
return *this;
}
//辅助函数
void Release()
{
if (_ptr && --GetRef() == 0)
{
Destory()(_ptr);
delete _pCount;
_pCount = NULL;
}
}
//析构函数
~SharedPtr()
{
Release();
}
int& GetRef()
{
return *_pCount;
}
private:
T* _ptr;
int* _pCount;
};
void Test2()
{
FILE* sp1 = fopen("test.txt", "rb");
SharedPtr sp2(sp1);
int* sp3 = (int*)malloc(sizeof(int));
SharedPtr >sp4(sp3);
int* sp5 = new int(1);
SharedPtr sp6(sp5);
}
int main()
{
Test2();
return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include
using namespace std;
#include"boost/shared_ptr.hpp"
struct Node
{
Node(int value)
:_value(value)
{
cout << "Node()" << endl;
}
~Node()
{
cout << "~Node()" << endl;
}
shared_ptr _prev;
shared_ptr _next;
int _value;
};
void Test2()
{
shared_ptr sp1(new Node(1));
shared_ptr sp2(new Node(2));
cout << sp1.use_count() << endl;
cout << sp2.use_count() << endl;
sp1->_next = sp2;
sp2->_prev = sp1;
cout << sp1.use_count() << endl;
cout << sp2.use_count() << endl;
}
int main()
{
Test2();
return 0;
}
上图只给出了简单的过程,下面贴出调用过程完整的源码:
shared_ptr() _NOEXCEPT
{ // construct empty shared_ptr
}
_Ptr_base()
: _Ptr(0), _Rep(0)
{ // construct
}
上面的构造函数连续调用了两次,构造节点内的_prev和_next。
template
explicit shared_ptr(_Ux *_Px)
{ // construct shared_ptr object that owns _Px
_Resetp(_Px);
}
_Ptr_base()
: _Ptr(0), _Rep(0)
{ // construct
}
template
void _Resetp(_Ux *_Px)
{ // release, take ownership of _Px
_TRY_BEGIN // allocate control block and reset
_Resetp0(_Px, new _Ref_count<_Ux>(_Px));
_CATCH_ALL // allocation failed, delete resource
delete _Px;
_RERAISE;
_CATCH_END
}
_Ref_count(_Ty *_Px)
: _Ref_count_base(), _Ptr(_Px)
{ // construct
}
_Ref_count_base()
{ // construct
_Init_atomic_counter(_Uses, 1);
_Init_atomic_counter(_Weaks, 1);
}
template
void _Resetp0(_Ux *_Px, _Ref_count_base *_Rx)
{ // release resource and take ownership of _Px
this->_Reset0(_Px, _Rx);
_Enable_shared(_Px, _Rx);
}
};
void _Reset0(_Ty *_Other_ptr, _Ref_count_base *_Other_rep)
{ // release resource and take new resource
if (_Rep != 0)
_Rep->_Decref();//没有执行
_Rep = _Other_rep;
_Ptr = _Other_ptr;
}
inline void _Enable_shared(const volatile void *, const volatile void *)
{ // not derived from enable_shared_from_this; do nothing
}
_Ty *operator->() const _NOEXCEPT
{ // return pointer to resource
return (this->_Get());
}
_Myt& operator=(const _Myt& _Right) _NOEXCEPT
{ // assign shared ownership of resource owned by _Right
shared_ptr(_Right).swap(*this);
return (*this);
}
shared_ptr(const _Myt& _Other) _NOEXCEPT
{ // construct shared_ptr object that owns same resource as _Other
this->_Reset(_Other);
}
_Ptr_base()
: _Ptr(0), _Rep(0)
{ // construct
}
template
void _Reset(const _Ptr_base<_Ty2>& _Other)
{ // release resource and take ownership of _Other._Ptr
_Reset(_Other._Ptr, _Other._Rep);
}
void _Reset(_Ty *_Other_ptr, _Ref_count_base *_Other_rep)
{ // release resource and take _Other_ptr through _Other_rep
if (_Other_rep)
_Other_rep->_Incref();
_Reset0(_Other_ptr, _Other_rep);
}
void _Incref()
{ // increment use count
_MT_INCR(_Mtx, _Uses);
}
void _Reset0(_Ty *_Other_ptr, _Ref_count_base *_Other_rep)
{ // release resource and take new resource
if (_Rep != 0)
_Rep->_Decref();
_Rep = _Other_rep;
_Ptr = _Other_ptr;
}
图1
~shared_ptr() _NOEXCEPT
{ // release resource
this->_Decref();
}
void _Decref()
{ // decrement reference count
if (_Rep != 0)
_Rep->_Decref();
}
void _Decref()
{ // decrement use count
if (_MT_DECR(_Mtx, _Uses) == 0)//uses为2,经过这条语句之后减为1
{ // destroy managed resource, decrement weak reference count
_Destroy();//不执行
_Decwref();//不执行
}
}
#define _CRT_SECURE_NO_WARNINGS 1
#include
using namespace std;
#include"boost/shared_ptr.hpp"
struct Node
{
Node(int value)
:_value(value)
{
cout << "Node()" << endl;
}
~Node()
{
cout << "~Node()" << endl;
}
weak_ptr _prev;
weak_ptr _next;
int _value;
};
void Test2()
{
shared_ptr sp1(new Node(1));
shared_ptr sp2(new Node(2));
cout << sp1.use_count() << endl;
cout << sp2.use_count() << endl;
sp1->_next = sp2;
sp2->_prev = sp1;
cout << sp1.use_count() << endl;
cout << sp2.use_count() << endl;
}
int main()
{
Test2();
return 0;
}
Node(int value)
:_value(value)
{
cout << "Node()" << endl;
}
//与上面的区别在这里(Node里的_prev和_next分别为weak_ptr智能指针)
weak_ptr() _NOEXCEPT
{ // construct empty weak_ptr object
}
_Ptr_base()
: _Ptr(0), _Rep(0)
{ // construct
}
上面过程同样连续执行两次(构造_prev和_next)
下面过程也是执行两次(构造sp1和sp2),和上面的过程相同
template
explicit shared_ptr(_Ux *_Px)
{ // construct shared_ptr object that owns _Px
_Resetp(_Px);
}
_Ptr_base()
: _Ptr(0), _Rep(0)
{ // construct
}
template
void _Resetp(_Ux *_Px)
{ // release, take ownership of _Px
_TRY_BEGIN // allocate control block and reset
_Resetp0(_Px, new _Ref_count<_Ux>(_Px));
_CATCH_ALL // allocation failed, delete resource
delete _Px;
_RERAISE;
_CATCH_END
}
_Ref_count(_Ty *_Px)
: _Ref_count_base(), _Ptr(_Px)
{ // construct
}
_Ref_count_base()
{ // construct
_Init_atomic_counter(_Uses, 1);
_Init_atomic_counter(_Weaks, 1);
}
template
void _Resetp0(_Ux *_Px, _Ref_count_base *_Rx)
{ // release resource and take ownership of _Px
this->_Reset0(_Px, _Rx);
_Enable_shared(_Px, _Rx);
}
};
void _Reset0(_Ty *_Other_ptr, _Ref_count_base *_Other_rep)
{ // release resource and take new resource
if (_Rep != 0)
_Rep->_Decref();
_Rep = _Other_rep;
_Ptr = _Other_ptr;
}
inline void _Enable_shared(const volatile void *, const volatile void *)
{ // not derived from enable_shared_from_this; do nothing
}
sp1->_next = sp2;
_Ty *operator->() const _NOEXCEPT
{ // return pointer to resource
return (this->_Get());
}
template
weak_ptr& operator=(const shared_ptr<_Ty2>& _Right) _NOEXCEPT//_Right就是sp2
{ // assign from _Right
this->_Resetw(_Right);
return (*this);
}
template
void _Resetw(const _Ptr_base<_Ty2>& _Other)//_Other为sp2
{ // release weak reference to resource and take _Other._Ptr
_Resetw(_Other._Ptr, _Other._Rep);
}
template
void _Resetw(_Ty2 *_Other_ptr, _Ref_count_base *_Other_rep)
{ // point to _Other_ptr through _Other_rep
if (_Other_rep)//增加sp2的弱引用计数,sp2.weaks加1 = 2
_Other_rep->_Incwref();
if (_Rep != 0)//sp1->next._Rep为0
_Rep->_Decwref();//不执行
_Rep = _Other_rep;//sp1->_next._Rep = sp2._Rep
_Ptr = _Other_ptr;//sp1->_next._Ptr = sp2._Ptr
}
void _Incwref()
{ // increment weak reference count
_MT_INCR(_Mtx, _Weaks);//将weaks从1修改为2
}
sp2->_prev = sp1;
_Ty *operator->() const _NOEXCEPT
{ // return pointer to resource
return (this->_Get());
}
template//_Right就是sp1
weak_ptr& operator=(const shared_ptr<_Ty2>& _Right) _NOEXCEPT
{ // assign from _Right
this->_Resetw(_Right);
return (*this);
}
template//_Other为sp1
void _Resetw(const _Ptr_base<_Ty2>& _Other)
{ // release weak reference to resource and take _Other._Ptr
_Resetw(_Other._Ptr, _Other._Rep);
}
template
void _Resetw(_Ty2 *_Other_ptr, _Ref_count_base *_Other_rep)
{ // point to _Other_ptr through _Other_rep
if (_Other_rep)//增加sp1的弱引用计数,sp1.weaks加1 = 2
_Other_rep->_Incwref();
if (_Rep != 0)//sp2->prev._Rep为0
_Rep->_Decwref();//不执行
_Rep = _Other_rep;//sp2->_prev._Rep = sp1._Rep
_Ptr = _Other_ptr;//sp2->_prev._Ptr = sp1._Ptr
}
void _Incwref()
{ // increment weak reference count
_MT_INCR(_Mtx, _Weaks);
}
//析构sp2
~shared_ptr()
{ // release resource
this->_Decref();
}
void _Decref()
{ // decrement reference count
if (_Rep != 0)//sp2._Rep不为0
_Rep->_Decref();
}
void _Decref()
{ // decrement use count
if (_MT_DECR(_Mtx, _Uses) == 0)//sp2.uses从1减为0
{ // destroy managed resource, decrement weak reference count
_Destroy();
_Decwref();
}
}
//释放节点空间(清理节点内资源(包括sp2->next和sp2->prev))
virtual void _Destroy()
{ // destroy managed resource
delete _Ptr;
}
-------------------------------------------------------------------------------------
下面都是清理sp2节点内的资源
~Node()
{
cout << "~Node()" << endl;
}
~weak_ptr()//清理sp2._next(弱智能指针)
{ // release resource
this->_Decwref();
}
void _Decwref()
{ // decrement weak reference count
if (_Rep != 0)//sp2->next._Rep为0
_Rep->_Decwref();//不执行
}
~weak_ptr()//清理sp2._prev
{ // release resource
this->_Decwref();
}
void _Decwref()/sp2->prev._Rep不为0(即就是sp1的引用计数空间存在)
{ // decrement weak reference count
if (_Rep != 0)/
_Rep->_Decwref();
}
void _Decwref()//sp2->prev._Weaks从2减为1(即就是将sp1._Weaks减为1)
{ // decrement weak reference count
if (_MT_DECR(_Mtx, _Weaks) == 0)
_Delete_this();//不执行
}
调用operator delete释放节点sp2的空间
void _Decwref()//释放sp2引用计数空间
{ // decrement weak reference count
if (_MT_DECR(_Mtx, _Weaks) == 0)//sp2._weaks从2减为1
_Delete_this();//不执行(也就是没有释放sp2的引用计数)
}
----------------------------------------------------------------------------
析构sp1
~shared_ptr()
{ // release resource
this->_Decref();
}
void _Decref()//减sp1的引用计数
{ // decrement reference count
if (_Rep != 0)//sp1._Rep不为0(sp1的引用计数不为空)
_Rep->_Decref();m
}
void _Decref()
{ // decrement use count
if (_MT_DECR(_Mtx, _Uses) == 0)//sp1._uses从1减为0
{ // destroy managed resource, decrement weak reference count
_Destroy();//释放节点空间
_Decwref();//释放sp1的引用计数
}
}
-------------------------------------------------------------------------------
清理sp1节点内资源
virtual void _Destroy()
{ // destroy managed resource
delete _Ptr;//释放sp1节点的空间(需要去清理节点内的资源(包括sp1->_next和sp1->_prev))
}
~weak_ptr()//清理sp1->next
{ // release resource
this->_Decwref();
}
void _Decwref()
{ // decrement weak reference count
if (_MT_DECR(_Mtx, _Weaks) == 0)//sp1->next._weaks从1减为0(即就是sp2._weaks减为0)
_Delete_this();//执行
}
virtual void _Delete_this()//释放了sp1->_next._Rep空间(即就是sp2的引用计数空间)
{ // destroy self
delete this;
}
~weak_ptr()//清理sp1._prev
{ // release resource
this->_Decwref();
}
void _Decwref()
{ // decrement weak reference count
if (_Rep != 0)//sp1->_prev._Rep为空
_Rep->_Decwref();//不执行
}
调用operator delete释放节点sp1空间
-----------------------------------------------------------------------------------------------------------
释放sp1引用计数空间
void _Decwref()
{ // decrement weak reference count
if (_MT_DECR(_Mtx, _Weaks) == 0)//sp1._weaks从1减为0
_Delete_this();
}
virtual void _Delete_this()//释放sp1引用计数的空间
{ // destroy self
delete this;
}
当有多个使用者使用同一个对象,而没有一个明显的拥有者时
当要把指针存入标准库容器时
当要传送对象到库或从库获取对象,而没有明确的所有权时
当管理一些需要特殊清除方式的资源时
通过定制删除器的帮助。