溫馨提示×

溫馨提示×

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

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

shared_ptr(下) 刪除器

發(fā)布時間:2020-10-05 20:45:00 來源:網(wǎng)絡(luò) 閱讀:1192 作者:匯天下豪杰 欄目:編程語言

1、shared_ptr中的px出現(xiàn)原因

  方便對其數(shù)據(jù)空間的管理,取值和獲取地址將極大的方便我們的操作。

2、解決析構(gòu)函數(shù)

  避免內(nèi)存空間的泄漏。new出來的空間都沒有釋放掉!

  釋放擁有權(quán)靠的是引用計數(shù)。

~shared_count(){ 
    if(pi){  //判斷所指父類是否為空
        pi->release(); //釋放new出來的對象和外部new出來的空間
    }
}
////////////////////////////////////////////////////////////////////////
public:
    virtual void dispose() = 0; //純虛函數(shù)
    void release(){  //在sp_counted_base中
        if(--use_count_ == 0){ //判斷use_count是否為0
            dispose();  //因為虛函數(shù),所以子類中實現(xiàn)
            delete this; //先調(diào)用析構(gòu)函數(shù),在釋放this指向的空間
        }    
    }
///////////////////////////////////////////////////////////////////////
public:
    void dispose(){
        delete px_; //釋放外部new出來的空間
    }

因為要級聯(lián)釋放空間,所以sp_counted_base的析構(gòu)函數(shù)必須是虛函數(shù),才能先調(diào)用子類的析構(gòu),最后調(diào)用自己的析構(gòu)函數(shù)。

結(jié)果如下:

shared_ptr(下) 刪除器

use_count和unique函數(shù)的實現(xiàn)比較簡單

3、拷貝構(gòu)造和賦值語句

  此時應(yīng)當(dāng)相當(dāng)于淺拷貝,use_count加1即可!模型如下:

shared_ptr(下) 刪除器

  此時應(yīng)在shared_ptr和shared_count進行淺拷貝,并在shared_count中加入方法,

    shared_count(shared_count const &r) : pi(r.pi){
        if(pi){
            pi->add_ref_copy(); //在父類中實現(xiàn)這個方法,只要讓++use_count_即可!
        }
    }

  賦值語句,關(guān)鍵調(diào)用swap函數(shù),的認真思考,畫畫圖就好理解多了(前面已經(jīng)寫過這個了)。

  這個賦值語句寫的真的很好,既讓use_count_加1,又可以讓原先的空間符合情況的釋放。

    shared_ptr<T>& operator=(shared_ptr<T> const &r){
        if(this != &r){
            this_type(r).swap(*this);//調(diào)用拷貝構(gòu)造,先創(chuàng)建一個無名臨時的對象,
        }                         //因為調(diào)用了拷貝構(gòu)造,所以在shared_count中調(diào)用方法,
        return *this;             //會讓use_count_加1的。
    }
//////////////////////////////////////////////////////////////////////////////////////
    void swap(shared_ptr<T> &other){
        std::swap(px, other.px); //指針的交換
        pn.swap(other.pn);
    }

3、shared_ptr的模擬部分:

#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 shared_ptr{
    typedef shared_ptr<T> this_type;
public:
    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)建一個無名臨時的對象
        }
        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);
    }
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{
public:
    template<class T>  //此時類型不定,寫模板函數(shù)
        shared_count(T *p) : pi(new sp_counted_impl_xx<T>(p)){
#ifdef DISPLAY
        cout<<"Create shared_cout object!"<<endl;
#endif
    }
    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;
    }
private:
    sp_counted_base *pi;
};

#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){
#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_;
    }
private:
    long use_count_;
};

#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"
using namespace std;

int main(void){
    int *p = new int(10);
    shared_ptr<int> ps(p);

    cout<<ps.use_count()<<endl;
    cout<<ps.unique()<<endl;

    shared_ptr<int> ps1 = ps;
    cout<<ps.use_count()<<endl;
    cout<<ps.unique()<<endl;
    shared_ptr<int> ps2;
    ps2 = ps;
    cout<<ps.use_count()<<endl;
    cout<<ps.unique()<<endl;

    //cout<<*ps<<endl;
    
}

以上就是對shared_ptr的部分源碼剖析的理解了。

4、刪除器

  刪除器d可以是一個函數(shù)對象(是一個對象,但是使用起來像函數(shù)),也可以是一個函數(shù)指針;

  可以根據(jù)自己定義的方式去管理(釋放)內(nèi)存空間。

  有2個特性:函數(shù)對象 operator()進行了重載

刪除器的使用,調(diào)用系統(tǒng)的:

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

void My_Deleter(int *p){ //刪除器
    cout<<"HaHa:"<<endl;
    delete p;
}
//靠刪除器來管理空間,而不再向之前的調(diào)用析構(gòu)函數(shù)。
int main(void){
    int *p = new int(10); //假設(shè)p是特殊的資源
    shared_ptr<int> ps(p, My_Deleter);
}

  回過頭來,對自己的空間進行釋放,定義自定義的刪除器。不采用默認方式釋放,而是

采用自己的方式釋放!

刪除器自己模擬部分代碼:

public:
    template<class Y, class D>
        shared_ptr(Y *p, D d) : px(p), pn(p, d){}//支持傳遞刪除器
/////////////////////////////////////////////////////////////////////////////
    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);
    }
///////////////////////////////////////////////////////////////////////////
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(){
        delete ptr;
    }
private:
    P ptr;
    D del;
};
//////////////////////////////////////////////////////////////////////////
#include<iostream>
#include"shared_ptr.h"
using namespace std;


void My_Deleter(int *p){ //刪除器
    cout<<"HaHa:"<<endl;
    delete p;
}

int main(void){
    int *p = new int(10); 
    shared_ptr<int> ps(p, My_Deleter);
}

以上就是刪除器實現(xiàn)的主要代碼,是在shared_ptr中實現(xiàn)的。




向AI問一下細節(jié)

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

AI