国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

設(shè)計模式學(xué)習(xí)(一)單例模式補(bǔ)充——單例模式析構(gòu)

這篇具有很好參考價值的文章主要介紹了設(shè)計模式學(xué)習(xí)(一)單例模式補(bǔ)充——單例模式析構(gòu)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

目錄
  • 前言
  • 無法調(diào)用析構(gòu)函數(shù)的原因
  • 改進(jìn)方法
    • 內(nèi)嵌回收類
    • 智能指針
    • 局部靜態(tài)變量
  • 參考文章

前言

在《單例模式學(xué)習(xí)》中提到了,在單例對象是通過new關(guān)鍵字動態(tài)分配在堆上的情況下,當(dāng)程序退出時,不會通過C++的RAII機(jī)制自動調(diào)用其析構(gòu)函數(shù)。本文討論一下這種現(xiàn)象的原因以及解決方法。

無法調(diào)用析構(gòu)函數(shù)的原因

在DCLP(雙檢查鎖模式)中,CSingleton中的instance是一個靜態(tài)指針變量,被分配在全局/靜態(tài)存儲區(qū)。而instance所指向的CSingleton實(shí)例是通過new創(chuàng)建在堆上的,只能手動調(diào)用delete來釋放相關(guān)資源(對于單例模式這是無法實(shí)現(xiàn)的,因?yàn)槲鰳?gòu)函數(shù)私有),無法通過RAII釋放相關(guān)資源。
在程序結(jié)束時,instance這個指針變量被銷毀了,但它所指向的內(nèi)存空間中的CSingleton對象并沒有被顯式銷毀,而是由操作系統(tǒng)去回收這一塊內(nèi)存(不會調(diào)用其析構(gòu)函數(shù))。然而依賴操作系統(tǒng)來清理資源并不是一個優(yōu)雅的結(jié)束方式,可能會造成文件句柄未關(guān)閉、網(wǎng)絡(luò)連接未斷開等資源泄漏。

class CSingleton
{
public:
    static CSingleton* getInstance();
    static std::mutex mtx;
private:
    CSingleton(){}
    ~CSingleton(){}
    CSingleton(const CSingleton&)			 = delete;
    CSingleton& operator=(const CSingleton&) = delete;

    static CSingleton* instance;
};

CSingleton* CSingleton::instance;

CSingleton* CSingleton::getInstance()
{
    if(nullptr == instance)
    {
        mtx.lock();
        if(nullptr == instance)
        {
            instance = new CSingleton();
        }
        mtx.unlock();
    }
    return instance;
}

改進(jìn)方法

在討論改進(jìn)方法時,我們還是傾向于利用C++的RAII機(jī)制,而不是手動去控制釋放的時機(jī)。

內(nèi)嵌回收類

我們的單例類對象生命周期的開始是在第一次調(diào)用時,結(jié)束是在程序結(jié)束時。

而且我們知道①靜態(tài)成員變量的生命周期是從程序啟動到結(jié)束②在靜態(tài)成員變量被銷毀時會調(diào)用其析構(gòu)函數(shù)

因此我們可以在單例類中定義一個用于釋放單例類資源的內(nèi)嵌類,將其析構(gòu)函數(shù)定義為顯式刪除單例對象的操作,然后在單例類中添加一個內(nèi)嵌類類型的靜態(tài)成員變量garbo。

這樣的話,在程序結(jié)束時garbo就會被銷毀,而RAII機(jī)制確保了在銷毀時會調(diào)用內(nèi)嵌類CGarbo的析構(gòu)函數(shù)。

因?yàn)樵?code>~CGarbo()中delete了CSingleton::instance,所以~CSingleton()就會被調(diào)用,相關(guān)資源得以釋放。

class CSingleton
{
public:
    static CSingleton* getInstance();
private:
    CSingleton(){std::cout<<"創(chuàng)建了一個對象"<< std::endl;}
    ~CSingleton(){std::cout<<"銷毀了一個對象"<< std::endl;}
    CSingleton(const CSingleton&) 			 = delete;
    CSingleton& operator=(const CSingleton&) = delete;
        
    static CSingleton* instance;
    static std::mutex mtx;
        
    class CGarbo    
    {
    public:
        CGarbo(){}
        ~CGarbo()
        {
            if(nullptr != CSingleton::instance)    //嵌套類可訪問外層類的私有成員
            {
                delete CSingleton::instance;
                instance = nullptr;
            }
             std::cout<<"Garbo worked"<< std::endl;
        }
    };
  
    static CGarbo garbo; //定義一個靜態(tài)成員,程序結(jié)束時,系統(tǒng)會自動調(diào)用它的析構(gòu)函數(shù)
    
};
  
CSingleton* CSingleton::instance;

std::mutex CSingleton::mtx;

CSingleton* CSingleton::getInstance()
{
    ...
}

CSingleton::CGarbo CSingleton::garbo;    //還需要初始化一個垃圾清理的靜態(tài)成員變量

運(yùn)行結(jié)果:
設(shè)計模式學(xué)習(xí)(一)單例模式補(bǔ)充——單例模式析構(gòu)

智能指針

我們還可以利用智能指針引用計數(shù)機(jī)制,對資源自動管理:

//編譯不通過
class CSingleton
{
public:
    static std::shared_ptr<CSingleton> getInstance(); 
private:
    CSingleton(){std::cout<<"創(chuàng)建了一個對象"<<std::endl;}
    ~CSingleton(){std::cout<<"銷毀了一個對象"<<std::endl;}
    CSingleton(const CSingleton&)            = delete;
    CSingleton& operator=(const CSingleton&) = delete;

    static std::shared_ptr<CSingleton> instance;
    static std::mutex mutex;
};

std::shared_ptr<CSingleton> CSingleton::instance;

std::mutex CSingleton::mutex;

std::shared_ptr<CSingleton> CSingleton::getInstance()
{
    if (nullptr == instance)
    {
        std::lock_guard<std::mutex> lock(mutex);
        if (nullptr == instance)
        {
            instance = std::shared_ptr<CSingleton>(new CSingleton());
        }
    }
    return instance; 
}

注意上述代碼無法通過編譯,原因是當(dāng)std::shared_ptr被銷毀時,它會嘗試使用delete來銷毀管理的對象。但因?yàn)镃Singleton的析構(gòu)函數(shù)是私有的,所以無法從外部手動銷毀CSingleton實(shí)例。

要解決這個問題,我們需要在CSingleton中自定義一個刪除器,讓std::shared_ptr能夠調(diào)用私有析構(gòu)函數(shù)。

class CSingleton
{
public:
    static std::shared_ptr<CSingleton> getInstance(); 
private:
    CSingleton(){std::cout<<"創(chuàng)建了一個對象"<<std::endl;}
    ~CSingleton(){std::cout<<"銷毀了一個對象"<<std::endl;}
    CSingleton(const CSingleton&)            = delete;
    CSingleton& operator=(const CSingleton&) = delete;

    static std::shared_ptr<CSingleton> instance;
    static std::mutex mutex;

    static void deleter(CSingleton* p); //自定義刪除器
};

std::shared_ptr<CSingleton> CSingleton::instance;

std::mutex CSingleton::mutex;

std::shared_ptr<CSingleton> CSingleton::getInstance()
{
    if (nullptr == instance)
    {
        std::lock_guard<std::mutex> lock(mutex);
        if (nullptr == instance)
        {
            instance = std::shared_ptr<CSingleton>(new CSingleton(),CSingleton::deleter);
        }
    }
    return instance; 
}

void CSingleton::deleter(CSingleton* p)
{
    delete p;
    std::cout<<"deleter worked"<<std::endl;
}

測試結(jié)果:
設(shè)計模式學(xué)習(xí)(一)單例模式補(bǔ)充——單例模式析構(gòu)

局部靜態(tài)變量

局部靜態(tài)變量形式的單例模式也可以完成資源的釋放,詳見《單例模式學(xué)習(xí)》。文章來源地址http://www.zghlxwxcb.cn/news/detail-841334.html

static CSingleton& getInstance() 
{
    static CSingleton instance;
    return instance;
}

參考文章

到了這里,關(guān)于設(shè)計模式學(xué)習(xí)(一)單例模式補(bǔ)充——單例模式析構(gòu)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 懶漢單例設(shè)計模式與餓漢單例設(shè)計模式

    單例模式即一個類確保只有一個對象,主要用于避免浪費(fèi)內(nèi)存 1 .餓漢單例設(shè)計模式 :拿到對象時,對象就早已經(jīng)創(chuàng)建好了 寫法: 把類的構(gòu)造器私有 在類中自己創(chuàng)建一個對象,并賦值到一個變量 定義一個靜態(tài)方法,返回自己創(chuàng)建的這個對象 2. 懶漢單例設(shè)計模式 :第一次拿到對象時

    2024年02月21日
    瀏覽(31)
  • 【設(shè)計模式】單例設(shè)計模式

    目錄 1、前言 2、基本語法 2.1、懶漢式單例 2.2、餓漢式單例 2.3、雙重檢驗(yàn)鎖單例模式 2.4、靜態(tài)內(nèi)部類單例模式 2.5、枚舉單例模式 2.6、ThreadLocal單例模式 2.7、注冊單例模式 3、使用場景 4、使用示例 5、常見問題 5、總結(jié) 單例模式是一種設(shè)計模式,它確保一個類只能創(chuàng)建一個實(shí)

    2024年02月09日
    瀏覽(29)
  • 【常用設(shè)計模式】待補(bǔ)充

    【常用設(shè)計模式】待補(bǔ)充

    Github倉庫地址 23中設(shè)計模型分為常見的三大類:創(chuàng)建型模式、結(jié)構(gòu)型模式和行為型模式 描述 簡單工廠模式不是23中設(shè)計模式中的。簡單工廠模式不直接向客戶端暴露對象創(chuàng)建的細(xì)節(jié),而是通過一個工廠類來負(fù)責(zé)創(chuàng)建產(chǎn)品類的實(shí)例 角色 抽象產(chǎn)品角色:給具體產(chǎn)品角色提供接口

    2024年02月08日
    瀏覽(21)
  • 【設(shè)計模式】單例模式|最常用的設(shè)計模式

    【設(shè)計模式】單例模式|最常用的設(shè)計模式

    單例模式是最常用的設(shè)計模式之一,雖然簡單,但是還是有一些小坑點(diǎn)需要注意。本文介紹單例模式并使用go語言實(shí)現(xiàn)一遍單例模式。 單例模式保證一個類僅有一個實(shí)例,并提供一個訪問它的全局訪問點(diǎn)。 使用場景: 當(dāng)類只能有一個實(shí)例而且可以從一個公開的眾所周知的訪

    2024年04月29日
    瀏覽(31)
  • 設(shè)計模式之單例設(shè)計模式

    就是一個類只允許創(chuàng)建一個對象,那么我們稱該類為單例類,這種設(shè)計模式我們稱為單例模式。 資源共享:有些類擁有共享的資源,例如數(shù)據(jù)庫連接池、線程池、緩存等。使用單例模式確保只有一個實(shí)例,避免資源浪費(fèi)和競爭條件。 線程安全:單例模式可以用來保證多線程

    2024年02月07日
    瀏覽(30)
  • 設(shè)計模式-單例模式

    ? ? ? 單例模式(Singleton Pattern)是設(shè)計模式中最簡單且最常用的一種創(chuàng)建型模式,其目的是保證一個類在整個系統(tǒng)中只存在一個實(shí)例,并提供全局訪問點(diǎn)來獲取這個唯一實(shí)例。這種模式主要適用于那些需要頻繁實(shí)例化然后又希望避免因?yàn)槎啻螌?shí)例化而消耗過多資源或產(chǎn)生副

    2024年01月17日
    瀏覽(26)
  • 設(shè)計模式——單例模式

    設(shè)計模式——單例模式

    確保某一個類只有一個實(shí)例,而且自行實(shí)例化并向整個系統(tǒng)提供這個實(shí)例。 即保證一個類只有一個實(shí)例,并且提供一個全局訪問點(diǎn) 優(yōu)點(diǎn) 單例對象在內(nèi)存中只有一個實(shí)例,減少了內(nèi)存的開支。尤其對于一個頻繁創(chuàng)建、銷毀的對象時,單例模式的優(yōu)勢就更明顯。 減少系統(tǒng)的性能

    2024年02月16日
    瀏覽(34)
  • 【設(shè)計模式-單例模式】

    【設(shè)計模式-單例模式】

    在一個項(xiàng)目中的全局范圍內(nèi), 一個類 有且僅有一個實(shí)例對象 。這個唯一的實(shí)例對象給其他模塊提供數(shù)據(jù)的 全局訪問 。這樣的模式就叫 單例模式 。 單例模式的典型例子就是任務(wù)隊列。 首先, 考慮單例模式的要求為有且僅有一個實(shí)例對象。那么就先從構(gòu)造函數(shù)入手。類的構(gòu)

    2024年02月13日
    瀏覽(32)
  • 設(shè)計模式(單例模式)

    ????????保證指定的類只有一個實(shí)例,不能創(chuàng)建出其他的實(shí)例 ? ? ? ? ? ? ? ? 1.1 代碼展示 ? ? ? ? ? ? ? ? 1.2 Singleton類中instance對象的創(chuàng)建時機(jī) ????????????????Singleton類中instance對象的創(chuàng)建時機(jī):在Singleton類被jvm加載的時候創(chuàng)建,Singleton類會在第一次使用的時

    2024年02月15日
    瀏覽(32)
  • 設(shè)計模式 ~ 單例模式

    單例模式:指在確保一個類只有一個實(shí)例,創(chuàng)建之后緩存以便繼續(xù)使用,并提供一個全局訪問點(diǎn)來訪問該實(shí)例; 前端對于單例模式不常用,但對于單例的思想無處不在; 如:彈窗、遮罩層、登錄框、vuex redux 中的 store; 閉包: 模塊化:

    2024年02月16日
    瀏覽(39)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包