码迷,mamicode.com
首页 > 其他好文 > 详细

共享智能指针shared_ptr的实现

时间:2019-08-20 21:50:45      阅读:86      评论:0      收藏:0      [点我收藏+]

标签:release   标准   运行   add   引用计数   rtu   line   图片   赋值   

     shared_ptr是一个最像指针的“智能指针”,是boost.smart_ptr库中最有价值、最重要的组成部分,也是最有用的,Boost库的许多组件——甚至还包括其他一些领域的智能指针都使用了shared_ptr,所以它被毫无悬念地收入了C++11标准。

     shared_ptr与scoped_ptr一样包装了new操作符在堆上分配的动态对象,但它实现的是引用计数型的智能指针0,可以被自由地拷贝和赋值,在任意的地方共享它,当没有代码使用(引用计数为0)它时才删除被包装的动态分配的对象。

shared_ptr也可以安全地放到标准容器中,是在STL容器中存储指针的最标准解法。

实现原理

技术图片

#include<iostream>
#include<vld.h>
using namespace std;

//shared_ptr
//#define TEST
class sharend_base
{
public:
    sharend_base():use_count(1)
    {
#ifdef TEST
        cout << "Create sharend_base object." << endl;
#endif
    }
    virtual void dispose() = 0;//纯虚函数
    virtual void destroy()
    {
        delete this;
    }
    void release()
    {
        if (--use_count == 0)
        {
            dispose();
            destroy();
        }
    }
    void add_uc()
    {
        ++use_count;
    }
    ~sharend_base()
    {
#ifdef TEST
        cout << "Free sharend_base object." << endl;
#endif
    }
    long u_count()const
    {
        return use_count;
    }
private:
    long use_count;
};

template<typename Y>
class sharend_conunt_impl:public sharend_base
{
public:
    sharend_conunt_impl():pi(nullptr)
    {
#ifdef TEST
        cout << "Create sharend_conunt_impl object." << endl;
#endif
    }
    sharend_conunt_impl(Y*p):_pi(p)
    {
#ifdef TEST
        cout << "Create sharend_conunt_impl object." << endl;
#endif
    }
    sharend_conunt_impl(sharend_conunt_impl<Y>&p) :_pi(p._pi)
    {
#ifdef TEST
        cout << "Create sharend_conunt_impl object." << endl;
#endif
    }
    sharend_conunt_impl& operator=(sharend_conunt_impl&tm)
    {
        _pi = tm._pi;
    }
    ~sharend_conunt_impl()
    {
        _pi=nullptr;
#ifdef TEST
        cout << "Free sharend_conunt_impl object." << endl;
#endif
    }
    void destroy()
    {
        delete this;
    }
    void dispose()
    {
        delete _pi;
    }
private:
    Y*_pi;
};

class sharend_conunt
{
public:
    sharend_conunt():pe()
    {
#ifdef TEST
        cout << "Create shared_conunt object." << endl;
#endif
    }
    template <typename V>
    sharend_conunt(V*p):pe(new sharend_conunt_impl<V>(p))
    {
#ifdef TEST
        cout << "Create shared_conunt object." << endl;
#endif
    }
    sharend_conunt(sharend_conunt &p):pe(p.pe)
    {
        if (pe)
            pe->add_uc();
#ifdef TEST
        cout << "Create shared_conunt object." << endl;
#endif
    }
    ~sharend_conunt()
    {
        if (pe)
            pe->release();
#ifdef TEST
        cout << "Free shared_conunt object." << endl;
#endif
    }
    sharend_conunt& operator=(const sharend_conunt&tem)
    {
        if (this != &tem)
        {
            pe = tem.pe;
            if (pe)
                pe->add_uc();
        }
        return *this;
    }
    long count()const
    {
        return pe->u_count();
    }
private:
    sharend_base *pe; 
};

template<typename T>
class shared_ptr
{
public:
    shared_ptr():px(nullptr),pn()
    {
#ifdef TEST
        cout << "Create shared_ptr object." << endl;
#endif
    }
    shared_ptr(T*p):px(p),pn(p)
    {
        cout << "Create shared_ptr object." << endl;
    }
    shared_ptr(shared_ptr<T>& r):px(r.px),pn(r.pn)
    {
#ifdef TEST
        cout << "Create shared_ptr object." << endl;
#endif
    }
    ~shared_ptr()
    {
#ifdef TEST
        cout << "Free shared_ptr object." << endl;
#endif
    }
    void count()const
    {
        cout << "use_count="<< pn.count() << endl;
    }
    typedef shared_ptr<T> this_type;
    shared_ptr& operator=(const shared_ptr &tmp)
    {
        if (this != &tmp)
        {
            px = tmp.px;
            pn = tmp.pn;
        }
        return *this;
    }
    T & operator*()const
    {
        return *px;
    }
    T*operator->()const
    {
        return px;
    }
private:
    T*px;
    sharend_conunt pn;
};

主函数:

void main(){        int *ptr = new int(10);
    shared_ptr<int> ps(ptr);
    cout <<*ps<<endl;
    ps.count();
    {
        shared_ptr<int> pt = ps;
        ps.count();
    }
    ps.count();
    shared_ptr<int> pt;
    pt = ps;
    ps.count();}

小编实现的是只有一些基础功能的,真正的还要看源码。

这里面要注意的就是sharend_conunt_impl这个类的子类对象要进行自杀,否则会出现内存泄漏。

下面就是vld.h头文件中的检查内存泄漏问题,这里是没有内存泄漏的所以:

技术图片

运行结果:

技术图片


---------------------------------------------------------------------------------------------------------------------------------------------------

         无冥冥之志者,无昭昭之明,无惛惛之事者,无赫赫之功!

共享智能指针shared_ptr的实现

标签:release   标准   运行   add   引用计数   rtu   line   图片   赋值   

原文地址:https://www.cnblogs.com/ycw1024/p/11385665.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!