【Linux】設計模式---單例模式

doctor_xiong發表於2018-02-21

概念:單例模式即在單例類例項化物件的時候只能例項化出來一個物件。
單例模式實現的要點:

  1. 單例類只能例項化出來一個單例物件
  2. 必須能夠自行建立例項物件
  3. 必須能夠向整個系統提供這個實力物件

單例模式的優點:

  • 單例模式只能夠建立一個物件,所以在資源方面可以做到節約記憶體資源
  • 單例模式不需要頻繁的銷燬和建立,所以在效率方面有所提高
  • 單例物件在整個系統裡面只有一份,可以做到避免共享資源的重複佔用
  • 單例模式的物件必須可以向整個系統提供,所以可以做到全域性

實現單例模式的方法有餓漢式和懶漢式兩種方法:

  1. 餓漢式是在單例類建立單例物件的時候就new出來物件空間
  2. 懶漢式是在呼叫get方法的時候才new出來物件空間

單執行緒下面的懶漢式


#include<iostream>
using namespace std;


class singleton{
    public:
    static singleton* GetInstance(){
        static singleton* pinstace;  //定義靜態單例物件的指標
        if(NULL == pinstance)   //判斷pinstace是否初始化
            pinstace = new singleton();
        return pinstance;
    }
    private:

    singleton(){}       //私有的建構函式
};

注:這個 類在單執行緒系統裡面是沒有問題的,但是在多執行緒系統裡面就會出現問題,假如在多執行緒裡面有兩個執行緒同時執行單例類,這樣的話在if語句判斷的時候就會假象的以為pinstance為NULL,那麼在系統裡面建立的單例類就會出現兩個 單例物件。

改進的懶漢式單例模式:


class singleton{
    public:
    static singleton* GetInstance(){

        lock();//加上訊號量互斥機制,給程式碼上鎖
        static singleton* pinstace;
        if(NULL == pinstance)
            pinstace = new singleton();

        unlock();
        return pinstance;
    }
    private:

    singleton(){}
};

注:懶漢式的單例模式是以空間換時間的方法

餓漢式的單例模式


class singleton{
    public:
    static singleton* GetInstance(){
        return instace;
    }
    private:
    static instace = new singleton();
    singleton(){}
};

注:這樣並不是一個好的做法,可以將靜態變數來封裝成一個類,利用封裝的類來操作,這樣可以更好的做到類的封裝性。

class SingleTon;  
SingleTon* getSingleTonInstance(){  
    static SingleTon* instance = new SingleTon();   
    return instance;  
}  
class SingleTon{  
    friend SingleTon* getSingleTonInstance();  
private:  
    SingleTon(){}  
};

注:在這上面的實現單例模式的方法中,存在做大的問題就是記憶體洩漏。
解決這個問題的方法可以在單例類裡面定義一個鑲嵌的內部類來解決。




class singleton{
    public:
    static singleton* GetInstance(){

        lock();
        static singleton* pinstace;
        if(NULL == pinstance)
            pinstace = new singleton();

        unlock();
        return pinstance;
    }
    class Del{
        ~Del(){
            if(singleton::instance != NULL){
                delete singleton::instance;
            } 
        }
    }
    private:
    static Del del;
    singleton(){}
};

當內嵌類的物件被銷燬的時候就會呼叫該物件的解構函式,從而達到銷燬單例物件的空間。

相關文章