您的位置:首页 > 运维架构

智能指针--scoped_ptr shared_ptr weak_ptr

2017-08-11 13:01 417 查看
所谓智能指针就是智能/自动化的管理指针所指向的动态资源的释放;

scopde_ptr--防拷贝

什么叫做防拷贝?就是不允许一个地址空间的指针赋值给另一个指针,导致有两个指针指向同一个地址;也就是说防拷贝能保证地址与指针是一一对应的关系;

实现方法:要拷贝,就需要通过对象来调用赋值运算符重载函数/拷贝构造函数,只要将这两个成员函数私有化/保护化,就ok啦;

具体代码:

 

template<class T>
class ScopedePtr
{
public:
ScopedePtr(T *ptr)
:_ptr(ptr)
{}
~ScopedePtr()
{
delete _ptr;
}

T* GetPtr()
{
return _ptr;
}
T& operator*()
{
return *_ptr;
}
T* operator->()
{
return _ptr;
}
protected:
ScopedePtr<T>& operator=(const ScopedePtr<T> &sp);
ScopedePtr(const ScopedePtr<T> &sp);

protected:
T *_ptr;
};
shared_ptr--引用计数

允许多个指向同一块地址;每增加一个指向该地址的指针计数器就加一;减少一个指向该地址的指针计数器减一,直到计数器的值为0的时候进行delete释放这块空间;

代码:

template<class T>
class SharedPtr
{
SharedPtr(T * ptr)
:_ptr(ptr)
, _ptrCount(new int(1))
{
}
~SharedPtr()
{
if (*_ptrCount == 0)
{
delete _ptr;
}
}

T& operator*()
{
return *_ptr;
}
T* operator->()
{
return _ptr;
}

SharedPtr<T>& operator=(const SharedPtr<T>& sp)
{
Release();
_ptr = sp._ptr;
_ptrCount = sp._ptrCount;
(*_ptrCount)++;
}

SharedPtr(const SharedPtr<T>& sp)
:_ptr(sp._ptr)
{
_ptrCount = sp._ptrCount;
(*_ptrCount)++;
}

void Release()
{
if (*_ptrCount != 0)
(*_ptrCount)--;
}

protected:
T *_ptr;
int *_ptrCount;
};
但是share_ptr有一个循环引用的问题:



当在双向链表时,想要释放p1但是p2->_prev指向p1,引用计数为1,想要释放p1必须先释放p2;对于p2而言想要释放也必须先释放p1;这就构成了循环引用问题,两者都不能释放;

weak_ptr就应运而生,专们用来辅助shared_ptr;

weak_ptr对象
a4cb
引用资源时不会增加引用计数,但是它能够通过lock()方法来判断它所管理的资源是否被释放。另外很自然地一个问题是:既然weak_ptr不增加资源的引用计数,那么在使用weak_ptr对象的时候,资源被突然释放了怎么办呢?呵呵,答案是你根本不能直接通过weak_ptr来访问资源。那么如何通过weak_ptr来间接访问资源呢?答案是:在需要访问资源的时候weak_ptr为你生成一个shared_ptr,shared_ptr能够保证在shared_ptr没有被释放之前,其所管理的资源是不会被释放的。创建shared_ptr的方法就是lock()方法。

弱指针当引用的对象活着的时候不一定存在。仅仅是当它存在的时候的一个引用。弱指针并不修改该对象的引用计数,这意味这弱指针它并不对对象的内存进行管理,在功能上类似于普通指针,然而一个比较大的区别是,弱指针能检测到所管理的对象是否已经被释放,从而避免访问非法内存

template<typename T> class weak_ptr {
public:
template <typename Y>
weak_ptr(const shared_ptr<Y>& r);

weak_ptr(const weak_ptr& r);

~weak_ptr();

T* get() const;
bool expired() const;
shared_ptr<T> lock() const;
};
expired()用于检测所管理的对象是否已经释放;lock()用于获取所管理的对象的强引用指针。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐