中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

三種單例模式的C++實現

發布時間:2020-07-17 19:45:37 來源:網絡 閱讀:424 作者:拳四郎 欄目:開發技術

簡介

        因為在設計或開發中,肯定會有這么一種情況,一個類只能有一個對象被創建,如果有多個對象的話,可能會導致狀態的混亂和不一致。這種情況下,單例模式是最恰當的解決辦法。它有很多種實現方式,各自的特性不相同,使用的情形也不相同。今天要實現的是常用的三種,分別是餓漢式、懶漢式和多線程式。

        通過單例模式, 可以做到:

1. 確保一個類只有一個實例被建立
2. 提供了一個對對象的全局訪問指針
3. 在不影響單例類的客戶端的情況下允許將來有多個實例


懶漢式

      懶漢式的特點是延遲加載,比如配置文件,采用懶漢式的方法,顧名思義,懶漢么,很懶的,配置文件的實例直到用到的時候才會加載。。。。。。

class CSingleton { public: static CSingleton* GetInstance() {      if ( m_pInstance == NULL )            m_pInstance = new CSingleton();      return m_pInstance; } private:     CSingleton(){};     static CSingleton * m_pInstance; };

GetInstance()使用懶惰初始化,也就是說它的返回值是當這個函數首次被訪問時被創建的。這是一種防彈設計——所有GetInstance()之后的調用都返回相同實例的指針:
CSingleton* p1 = CSingleton :: GetInstance();
CSingleton* p2 = p1->GetInstance();
CSingleton & ref = * CSingleton :: GetInstance();
對GetInstance稍加修改,這個設計模板便可以適用于可變多實例情況,如一個類允許最多五個實例。


代碼很簡單,但是會存在內存泄漏的問題,new出來的東西始終沒有釋放,下面是一種餓漢式的一種改進。

class CSingleton   {   private:       CSingleton()       {       }       static CSingleton *m_pInstance;       class CGarbo        {       public:           ~CGarbo()           {               if(CSingleton::m_pInstance)                   delete CSingleton::m_pInstance;           }       };       static CGarbo Garbo;    public:       static CSingleton * GetInstance()       {           if(m_pInstance == NULL)               m_pInstance = new CSingleton();           return m_pInstance;       }   };  

    在程序運行結束時,系統會調用CSingleton的靜態成員Garbo的析構函數,該析構函數會刪除單例的唯一實例。使用這種方法釋放單例對象有以下特征:
1.在單例類內部定義專有的嵌套類。
2.在單例類內定義私有的專門用于釋放的靜態成員。
3.利用程序在結束時析構全局變量的特性,選擇最終的釋放時機。


餓漢式

       餓漢式的特點是一開始就加載了,如果說懶漢式是“時間換空間”,那么餓漢式就是“空間換時間”,因為一開始就創建了實例,所以每次用到的之后直接返回就好了。

class CSingleton   {   private:       CSingleton()         {       }   public:       static CSingleton * GetInstance()       {           static CSingleton instance;            return &instance;       }   };  

      餓漢式是線程安全的,在類創建的同時就已經創建好一個靜態的對象供系統使用,以后不再改變,懶漢式如果在創建實例對象時不加上synchronized則會導致對對象的訪問不是線程安全的。

注:線程安全的通俗解釋 - 不管多個線程是怎樣的執行順序和優先級,或是wait,sleep,join等控制方式,如果一個類在多線程訪問下運轉一切正常,并且訪問類不需要進行額外的同步處理或者協調,那么我們就認為它是線程安全的。 線程安全的類應當封裝了所有必要的同步操作,調用者無需額外的同步。還有一點:無狀態的類永遠是線程安全的。

        

         在餓漢式的單例類中,其實有兩個狀態,單例未初始化和單例已經初始化。假設單例還未初始化,有兩個線程同時調用GetInstance方法,這時執行 m_pInstance == NULL 肯定為真,然后兩個線程都初始化一個單例,最后得到的指針并不是指向同一個地方,不滿足單例類的定義了,所以餓漢式的寫法會出現線程安全的問題!在多線程環境下,要對其進行修改。


多線程下的單例模式

        這里要處理的是懶漢模式。

class Singleton { private:     static Singleton* m_instance;     Singleton(){} public:     static Singleton* getInstance(); };  Singleton* Singleton::getInstance() {     if(NULL == m_instance)     {         Lock();//借用其它類來實現,如boost         if(NULL == m_instance)         {             m_instance = new Singleton;         }         UnLock();     }     return m_instance; }

使用double-check來保證thread safety.但是如果處理大量數據時,該鎖才成為嚴重的性能瓶頸。


參考

C++中的單例模式

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

商南县| 宜兰市| 崇文区| 富锦市| 桐庐县| 如东县| 怀柔区| 潮安县| 西和县| 兰考县| 宁德市| 伊吾县| 江门市| 元朗区| 滁州市| 隆子县| 民和| 万全县| 石阡县| 孙吴县| 宝鸡市| 溧阳市| 新乡市| 高阳县| 嘉善县| 青田县| 钟祥市| 南汇区| 兴城市| 保德县| 同江市| 乌鲁木齐县| 威信县| 高要市| 禹城市| 隆安县| 宿松县| 南木林县| 武威市| 电白县| 芒康县|