您的位置:首页 > 编程语言 > C语言/C++

C++智能指针shared_ptr剖析

2017-02-23 13:28 615 查看
shared_ptr是c++智能指针中适用场景多,功能实现较多的智能指针。它采取引用计数的方法来实现释放指针所指向的资源。下面是我代码实现的基本功能。

template<class T>
class sharedptr
{
public:
sharedptr(T* ptr)
:_ptr(ptr)
, _refCount(new int(1))
{}

sharedptr(sharedptr<T>& sp)
:_ptr(sp._ptr)
, _refCount(sp._refCount)
{
++(*_refCount);
}
sharedptr& operator = (sharedptr<T>& sp)  //现代写法
{
swap(_ptr, sp._ptr);
swap(_refCount, sp._refCount);
return *this;
}

/*sharedptr& operator = (sharedptr<T>& sp)
{
if (this != &sp)
{
this->Release();

_ptr = sp._ptr;
_refCount = sp._refCount;
++(*_refCount);
}
return *this;
}*/
void Release()
{
if (--(*_refCount) == 0)
{
delete _ptr;
delete _refCount;
}
}
~sharedptr()
{
Release();
}
private:
T* _ptr;
int* _refCount;
};


但是呢这只能删除基本类型,例int、double类型指针。但对于数组指针不是适用。在c++中动态内存管理中,new/delete对应,new[]/delete[]对应,所以就引入了定制删除器这个概念。

定制删除器基本的实现就是:

template<class T>
struct Delete
{
void operator()(T* ptr)
{
delete ptr;
}
};

template<class T>
struct DeleteArray
{
void operator()(T* ptr)
{
delete[] ptr;
}
};


如何在shared_ptr中使用呢,下来我用代码简单做个示范。

template<class T> //定制删除器
struct Delete
{
void operator()(T* ptr)
{
delete ptr;
}
};

template<class T>//定制删除器
struct DeleteArray
{
void operator()(T* ptr)
{
delete[] ptr;
}
};

template<class T, class D = Delete<T>>
class sharedptr
{
public:
sharedptr(T* ptr, D del)
:_ptr(ptr)
, _refCount(new int(1))
, _del(del)
{}

sharedptr(sharedptr<T>& sp)
:_ptr(sp._ptr)
, _refCount(sp._refCount)
{
++(*_refCount);
}
sharedptr& operator = (sharedptr<T>& sp)  //现代写法
{
swap(_ptr, sp._ptr);
swap(_refCount, sp._refCount);
return *this;
}

/*sharedptr& operator = (sharedptr<T>& sp)
{
if (this != &sp)
{
this->Release();

_ptr = sp._ptr;
_refCount = sp._refCount;
++(*_refCount);
}
return *this;
}*/
void Release()
{
if (--(*_refCount) == 0)
{
printf("delete:0x%p\n", _ptr);
_del(_ptr);
delete _refCount;
}
}
~sharedptr()
{
Release();
}
private:
T* _ptr;
int* _refCount;
D _del;
};


在调用时,应这样写调用函数:

void TextSharedptr()
{
DeleteArray<int> da;
sharedptr<int, DeleteArray<int>> sp(new int[3], da);

}


而weak_ptr弱引用智能指针是通过(引用不增加计数)来打破循环引用的;

什么循环引用,这可以简单用一个双向链表来解释:



而weak_ptr通过只引用不增加计数的方法打破了循环引用这个问题。但在使用weak_ptr的前提是确定在使用shared_ptr智能指针时存在循环引用这个问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息