智能指针---shared_ptr和weak_ptr

智能指针主要解决被多个对象引用时,资源如何释放的问题。

下面介绍一下boost库中的shared_ptr和weak_ptr:

Shared_ptr:当进行拷贝和赋值操作时, shared_ptr所指向的对象的引用计数都会增加,一旦变为0,就会自动释放自己管理的对象。(shared_ptr所指向的对象有一个被释放时,引用计数就会减1)

Weak_ptr: weak_ptr是一种不控制所指向对象生存周期的智能指针,它指向一个shared_ptr管理的对象时,并不会改变对象的引用计数(引用计数不增加),一旦最后一个指向shared_ptr的对象被销毁,对象就会被释放,即使有weak_ptr指向该对象,还是会被释放。

当创建一个weak_ptr时,要用一个shared_ptr来初始化,由于对象可能不存在,我们不能使用weak_ptr来访问对象,通过调用lock()方法,检查对象是否存在,若存在,则返回一个指向共享对象的shared_ptr.

原理:在创建共享对象时,要使用强指针 shared_ptr,若将该对象给其他线程时,则需要将强指针 shared_ptr转化为弱指针weak_ptr
(强指针的引用计数会增加,不转化为弱指针则一旦被其他线程调用,则该对象将一直不能析构,weak_ptr对象引用资源不会增加引用计数)要是弱指针weak_ptr想访问该对象时,不能通过weak_ptr来直接访问资源,需要进行提升(shared_ptr能保证自己没被释放之前,所管理的资源是不会被释放的,当shared_ptr引用计数为0时,释放资源,即使有weak_ptr指向它,而weak_ptr通过lock()方法来判断所管理的资源是否被释放,访问时要进行提升)weak_ptr为shared_ptr,将该弱指针提升为强指针,若提升成功,指针不为空,否则为空。

这里写图片描述

重磅推荐《linux多线程服务器编程》—第一章1.6节 神器shared_ptr/weak_ptr 书目作者陈硕(很腻害的一个大神)

附上一个自己实现的智能指针,通过链表来存储这些被引用的资源,当我们在实现指针的拷贝,赋值,析构等操作时,资源引用计数会相应的增加和减少。会遍历链表找到该资源的类型,对该资源计数引用增加减少,若计数减少为0时,则释放该资源节点。

//智能指针
class HeapTable//给资源上的指针计数
{
public:
     static HeapTable *Getinstance()//单例  不同类型实例化只能在同一个链表
     {
             static HeapTable  mHeapTable;
             return &mHeapTable;
     }
     ~HeapTable()
     {
         Node *pcur=phead;
         while (pcur != NULL)
         {
             phead=phead->mpnext;
             delete pcur;
             pcur=phead;
         }
     }
    void addRef(void *ptr)
    {
        Node *pcur=phead->mpnext;
        while (pcur != NULL)
        {
            if (pcur->paddr == ptr)//查找到对该资源计数器加1
            {
                pcur->mcount++;
                return;
            }
            pcur=pcur->mpnext;
        }
        pcur=new Node;//没查找到 进行头插
        pcur->mpnext=phead->mpnext;
        phead->mpnext=pcur;

    }
    void delRef(void *ptr)
    {
        Node *pcur=phead->mpnext;
        while (pcur != NULL)
        {
            if (pcur->paddr == ptr)//查找到对该资源计数器减1
            {
                pcur->mcount--;
                return;
            }
            pcur=pcur->mpnext;
        }
    }
    int GetRef(void *ptr)
    {
        Node *pcur=phead->mpnext;
        while (pcur != NULL)
        {
            if (pcur->paddr == ptr)
            {
                return pcur->mcount;
            }
            pcur=pcur->mpnext;
        }
        return -1;
    }

private:
    HeapTable(){phead = new Node;}
    class Node
    {
    public:Node(void *ptr=NULL):mcount(0),paddr(ptr),mpnext(NULL)
           {
               if (paddr != NULL)
               {
                   mcount=1;
               }
           }
        int mcount;
        void *paddr;//指向资源
        Node *mpnext;
    };
    Node *phead;
};

template<typename T>
class CsmartPtr
{
public:
    CsmartPtr(T* str = NULL):mpstr(str)//构造
    {
        if (mpstr != NULL)
        {
            addRef();
        }
    }

    CsmartPtr(const CsmartPtr<T> &src):mpstr(src.mpstr)//拷贝构造
    {
        if (mpstr != NULL)
        {
            addRef();
        }
    }

    CsmartPtr<T>& operator=(const CsmartPtr<T> &src)//赋值运算符重载
    {
        if (this == &src)//防止自赋值
        {
            return *this;
        }
        if (mpstr != NULL)//释放原来的空间
        {
            delRef();
            if (GetRef() == 0)
            {
                delete mpstr;
                mpstr=NULL;
            }   
        }

        mpstr=src.mpstr;
         addRef();
        return *this;
    }

    ~CsmartPtr()
    {
        cout<<"this"<<this<<endl;
        delRef();
        if (GetRef() == 0)
        {
            delete mpstr;
            mpstr=NULL;
        }
    }

    T & operator *(){return *mpstr;}
    const T & operator *()const{return *mpstr;}

    T* operator ->(){return mpstr;}
    const T * operator ->()const{return mpstr;}

    void addRef(){ mpHeapTab->addRef(mpstr);}
    void delRef(){ mpHeapTab->delRef(mpstr);}
    int GetRef() {return mpHeapTab->GetRef(mpstr);}


private:
    T *mpstr;
    static HeapTable *mpHeapTab;//静态指针
};

//静态变量在全局进行初始化
template<typename T>
HeapTable*CsmartPtr<T>::mpHeapTab=HeapTable::Getinstance();

int main()
{
    int *p = new int;

    CsmartPtr<int>pointer1(new int);
    CsmartPtr<int>pointer2(new int);
    CsmartPtr<int>pointer3(pointer1);
    pointer2=pointer1;

    CsmartPtr<char> pointer4((char*)p);

    return 0;
}

这里写图片描述

发布了47 篇原创文章 · 获赞 8 · 访问量 3万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览