,它的..."/>
溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

weak_ptr和intrusive_ptr

發(fā)布時(shí)間:2020-07-02 04:12:07 來(lái)源:網(wǎng)絡(luò) 閱讀:512 作者:匯天下豪杰 欄目:編程語(yǔ)言

1、weak_ptr

  (1)、weak_ptr是為了配合shared_ptr而引入的智能指針,它更像是shared_ptr的一個(gè)助手,它不具有普通指針的行為,

沒(méi)有重載operator*和->,它的最大作用在于協(xié)助shared_ptr工作,像旁觀者那樣觀測(cè)資源的使用情況。

  (2)、2個(gè)重要接口:bool expired()const ;// 判斷是否過(guò)期

  lock()函數(shù)是弱指針的核心;

  (3)、獲得資源的觀測(cè)權(quán),但weak_ptr沒(méi)有共享資源,它的構(gòu)造不會(huì)引起引用計(jì)數(shù)的增加,它的析構(gòu)也不會(huì)導(dǎo)致引用計(jì)數(shù)減少,

它只是一個(gè)靜靜的觀察者。

2、使用weak_ptr

  調(diào)用系統(tǒng)庫(kù)的:

#include<iostream>
#include<boost/smart_ptr.hpp>
using namespace std;
using namespace boost;

int main(void){
    int *p = new int(10);
    shared_ptr<int> sp(p);
    
    weak_ptr<int> wp(sp);//1、本身對(duì)wp的創(chuàng)建與析構(gòu)是不會(huì)增加/減少use_count;
    cout<<wp.use_count()<<endl;//2、顯示的是它所觀測(cè)對(duì)象的引用計(jì)數(shù)器

    if(!wp.expired()){  //沒(méi)過(guò)期(use_count != 0,空間還沒(méi)釋放)
        shared_ptr<int> sp1 = wp.lock();
        //3、wp的lock()函數(shù)在有效的前提下可以構(gòu)造對(duì)象(構(gòu)造的是所觀測(cè)的對(duì)象)。
        //使use_count加1;
    }//失效的話,構(gòu)建的是一個(gè)空對(duì)象,引用計(jì)數(shù)將不會(huì)在增加?。。?
}

 3、weak_ptr源碼剖析

  結(jié)合shared_ptr和前面的所有,刪除器,shared_array、weak_ptr給出模擬的部分代碼:

  模仿源代碼,寫出了最重要的函數(shù):

#ifndef _CONFIG_H_
#define _CONFIG_H_

#include<iostream>
using namespace std;

//#define DISPLAY

#endif
//////////////////////////////////////////////////////////////////////////////////////////
#ifndef _SHARED_PTR_H_
#define _SHARED_PTR_H_

#include"shared_count.h"

template<class T>
class weak_ptr;

template<class T>
class shared_ptr{
    friend class weak_ptr<T>;
    typedef shared_ptr<T> this_type;
public:
    template<class Y, class D>
        shared_ptr(Y *p, D d) : px(p), pn(p, d){}//支持傳遞刪除器
    shared_ptr(T *p = 0) : px(p), pn(p){
#ifdef DISPLAY
        cout<<"Create shared_ptr object!"<<endl;
#endif
    }
    shared_ptr(shared_ptr<T> const &r) : px(r.px), pn(r.pn){}
    shared_ptr<T>& operator=(shared_ptr<T> const &r){
        if(this != &r){
            this_type(r).swap(*this);//調(diào)用拷貝構(gòu)造,先創(chuàng)建一個(gè)無(wú)名臨時(shí)的對(duì)象
        }
        return *this;
    }
    ~shared_ptr(){
#ifdef DISPLAY
        cout<<"Free shared_ptr object"<<endl;
#endif
    }
public:
    T& operator*()const{
        return *(get());
    }
    T* operator->()const{
        return get();
    }
    T* get()const{
        return px;
    }
public:
    long use_count()const{
        return pn.use_count();
    }
    bool unique()const{
        return pn.unique();
    }
    void reset(T *p){
        this_type(p).swap(*this);
    }
    void swap(shared_ptr<T> &other){
        std::swap(px, other.px); //指針的交換
        pn.swap(other.pn);
    }
public:
    template<class Y>
    shared_ptr(weak_ptr<Y> const &r) : pn(r.pn){
        px = r.px;
    }

private:
    T *px;
    shared_count pn;
};

#endif
/////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef _SHARED_COUNT_H_
#define _SHARED_COUNT_H_

#include"config.h"
#include"sp_counted_base.h"
#include"sp_counted_impl_xx.h"


class shared_count{
    friend class weak_count;
public:
    template<class T>  //此時(shí)類型不定,寫模板函數(shù)
        shared_count(T *p) : pi(new sp_counted_impl_xx<T>(p)){
#ifdef DISPLAY
        cout<<"Create shared_cout object!"<<endl;
#endif
    }
    template<class Y, class D>
    shared_count(Y *p, D d) : pi(0){
        typedef Y* P;
        pi = new sp_counted_impl_pd<P, D>(p, d);
    }
    shared_count(shared_count const &r) : pi(r.pi){
        if(pi){
            pi->add_ref_copy();
        }
    }
    ~shared_count(){
#ifdef DISPLAY
        cout<<"Free shared_count object"<<endl;
#endif
        if(pi){
            pi->release();
        }
    }
public:
    long use_count()const{
        return pi != 0 ? pi->use_count() : 0;
    }
    bool unique()const{
        return use_count() == 1;
    }
    void swap(shared_count &r){
        sp_counted_base *tmp = r.pi;
        r.pi = pi;
        pi = tmp;
    }
public:
    explicit shared_count(weak_count const &r);
private:
    sp_counted_base *pi;
};
/////////////////////////////////////////////////////
template<class P, class D>
class sp_counted_impl_pd : public sp_counted_base{
public:
    sp_counted_impl_pd(P p, D d) : ptr(p), del(d){}
public:
    void dispose(){
        del(ptr);
    }
private:
    P ptr;
    D del;
};
/////////////////////////////////////////////////////////////////////
class weak_count{
    friend class shared_count;
public:
    weak_count(shared_count const &r) : pi(r.pi){
        if(pi != 0){
            pi->weak_add_ref();
        }
    }
    ~weak_count(){
        if(pi){
            pi->weak_release();
        }
    }
public:
    long use_count()const{
        return pi != 0 ? pi->use_count() : 0;
    }
private:
    sp_counted_base *pi;
};

shared_count::shared_count(weak_count const &r) : pi(r.pi){
    if(pi){
        pi->add_ref_lock();
    }
}
#endif
//////////////////////////////////////////////////////////////////////////////
#ifndef SP_COUNTED_BASE_H_
#define SP_COUNTED_BASE_H_

#include"config.h"

class sp_counted_base{  //抽象類
public:
    sp_counted_base() : use_count_(1), weak_count_(1){
#ifdef DISPLAY
        cout<<"Create sp_counted_base object"<<endl;
#endif
    }
    virtual ~sp_counted_base(){
#ifdef DISPLAY
        cout<<"Free sp_counted_base object"<<endl;
#endif
    }
public:
    virtual void dispose() = 0; //純虛函數(shù)
    void release(){
        if(--use_count_ == 0){
            dispose();
            delete this;
        }    
    }
public:
    long use_count()const{
        return use_count_;
    }
    void add_ref_copy(){
        ++use_count_;
    }
    void weak_add_ref(){
        ++weak_count_;
    }
    virtual void destroy(){
        delete this;
    }
    void weak_release(){
        if(--weak_count_ == 0){
            destroy();
        }
    }
    bool add_ref_lock(){
        if(use_count == 0){
            return false;
        }
        ++use_count_;
        return true;
    }
private:
    long use_count_;
    long weak_count_;
};

#endif
/////////////////////////////////////////////////////////////////////////////////
#ifndef _SHARED_ARRAY_H_
#define _SHARED_ARRAY_H_

#include"checked_delete.h"

template<class T>
class shared_array{
public:
    typedef checked_array_deleter<T> deleter;
    shared_array(T *p = 0) : px(p), pn(p, deleter()){} //無(wú)名對(duì)象
    ~shared_array(){
        
    }
public:
    T& operator[](int i)const{
        return px[i];
    }
private:
    T *px;
    shared_count pn;  //必須用到引用計(jì)數(shù)器對(duì)象
};

#endif
////////////////////////////////////////////////////////////////////////////////////////////
#ifndef _CHECKED_DELETE_H_
#define _CHECKED_DELETE_H_

template<class T>
void checked_array_delete(T *x){
    delete []x;
}

template<class T>
struct checked_array_deleter{
public:
    void operator()(T *x)const{
        checked_array_delete(x);        
    }
};

#endif
//////////////////////////////////////////////////////////////////////////////////////////////
#ifndef _WEAK_PTR_H_
#define _WEAK_PTR_H_

#include"shared_ptr.h"

template<class T>
class shared_ptr;

class shared_count;
template<class T>
class weak_ptr{
    friend class shared_ptr<T>;
    friend class shared_count;
public:
    template<class Y>
    weak_ptr(shared_ptr<Y> const &r) : px(r.px), pn(r.pn){}
    ~weak_ptr(){}
public:
    long use_count()const{
        pn.use_count();
    }
    bool expired()const{
        return pn.use_count() == 0;
    }
    shared_ptr<T> lock()const{
        return shared_ptr<T>(*this);
    }
private:
    T *px;
    weak_count pn;
};

#endif
///////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef SP_COUNTED_IMPL_XX_H_
#define SP_COUNTED_IMPL_XX_H_

#include"sp_counted_base.h"

template<class T>
class sp_counted_impl_xx : public sp_counted_base{
public:
    sp_counted_impl_xx(T *p) : px_(p){
#ifdef DISPLAY
        cout<<"Create sp_counted_impl_xx object"<<endl;
#endif
    }
    ~sp_counted_impl_xx(){
#ifdef DISPLAY
        cout<<"Free sp_counted_impl_xx object"<<endl;
#endif
    }
public:
    void dispose(){
        delete px_;
    }
private:
    T *px_;
};

#endif
///////////////////////////////////////////////////////////////////////////////////////////////////////
#include<iostream>
#include"shared_ptr.h"
#include"shared_array.h"
#include"weak_ptr.h"
using namespace std;

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

    shared_ptr<int> sp(p);
    weak_ptr<int> wp(sp);
    if(!wp.expired()){
        shared_ptr<int> sp1 = wp.lock();//返回真實(shí)的對(duì)象
        cout<<sp.use_count()<<endl;
    }
    cout<<sp.use_count()<<endl;

}

這是這個(gè)智能指針的最主要的剖析,關(guān)鍵理清脈絡(luò),條理清晰一些,就可以分析出來(lái)!

4、intrusive_ptr的使用

  適用情景:(1)、對(duì)內(nèi)存的占用要求非常嚴(yán)格,不能有引用計(jì)數(shù)的內(nèi)存開(kāi)銷;

  (2)、這時(shí)的代碼中已經(jīng)有了引用計(jì)數(shù)機(jī)制管理的對(duì)象

重點(diǎn)掌握如何使用:

  (1)、兩個(gè)方法必須重寫(增加/減少引用計(jì)數(shù))

  (2)、必須自己編寫管理引用計(jì)數(shù)的類

  (3)、要封裝到一個(gè)類中,在繼承(把自己的類侵入到智能指針中進(jìn)行管理)

具體使用的一個(gè)類子如下:

#include<iostream>
#include<boost/smart_ptr.hpp>
using namespace std;
using namespace boost;
 
//1、實(shí)現(xiàn)2個(gè)重要的函數(shù)
template<class T>
void intrusive_ptr_add_ref(T *t){ //增加引用計(jì)數(shù)
    t->add_ref_copy();
}
template<class T>
void intrusive_ptr_release(T *t){  //減少引用計(jì)數(shù)
    t->release();
}

//2、提供管理對(duì)象
class Counter{
public:
    Counter() : use_count_(0){
    
    }
    ~Counter(){
    
    }
public:
    void add_ref_copy(){
        ++use_count_;
    }
    void release(){
        if(--use_count_ == 0){
            delete this;
        }
    }
private:
    long use_count_;
};
//3、定義自己的對(duì)象
class Test;
ostream& operator<<(ostream &out, const Test &t);
class Test : public Counter{
    friend     ostream& operator<<(ostream &out, const Test &t);
public:
    Test(int d = 0) : data(d){}
    ~Test(){}
private:
    int data;
};

ostream& operator<<(ostream &out, const Test &t){
    out<<t.data;
    return out;
}

int main(void){
    Test *pt = new Test(10);
    intrusive_ptr<Test> ip(pt);
    cout<<*ip<<endl;

}

結(jié)果如下:

weak_ptr和intrusive_ptr




向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI