概念:單例模式即在單例類實例化對象的時候只能實例化出來一個對象。
單例模式實現的要點:
- 單例類只能實例化出來一個單例對象
- 必須能夠自行創建實例對象
- 必須能夠向整個系統提供這個實力對象
單例模式的優點:
- 單例模式只能夠創建一個對象,所以在資源方面可以做到節約內存資源
- 單例模式不需要頻繁的銷燬和創建,所以在效率方面有所提高
- 單例對象在整個系統裏面只有一份,可以做到避免共享資源的重複佔用
- 單例模式的對象必須可以向整個系統提供,所以可以做到全局
實現單例模式的方法有餓漢式和懶漢式兩種方法:
- 餓漢式是在單例類創建單例對象的時候就new出來對象空間
- 懶漢式是在調用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(){}
};
當內嵌類的對象被銷燬的時候就會調用該對象的析構函數,從而達到銷燬單例對象的空間。