共享智能指针shared_ptr的实现

Posted ycw1024

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了共享智能指针shared_ptr的实现相关的知识,希望对你有一定的参考价值。

     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的实现的主要内容,如果未能解决你的问题,请参考以下文章

图解shared_ptr共享智能指针原理分析

[C++11]共享智能指针shared_ptr指定删除器

[C++11]shared_ptr共享智能指针的初始化与使用

Boost智能指针——shared_ptr

第21课 shared_ptr共享型智能指针

智能指针原理及实现- shared_ptr