程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 設計模式C++描述----01.單例(Singleton)模式

設計模式C++描述----01.單例(Singleton)模式

編輯:C++入門知識

一.概念

單例模式:其意圖是保證一個類僅有一個實例,並提供一個訪問它的全局訪問點,該實例被所有程序模塊共享。

[cpp]
class CSingleton 

//公有的靜態方法,來獲取該實例 
public: 
static CSingleton* GetInstance() 

    if ( m_pInstance == NULL )  //判斷是否第一次調用 
        m_pInstance = new CSingleton(); 
 
    return m_pInstance; 

 
//私有構造函數,防止實例化 
private: 
    CSingleton(){}; 
 
 
//私有靜態指針變量,指向類的唯一實例 
private: 
    static CSingleton * m_pInstance; //聲明一個靜態成員 
}; 
 
CSingleton* CSingleton::m_pInstance = NULL; //定義並初始化靜態數據成員 
 
int main() 

    CSingleton* ps1 = CSingleton::GetInstance(); 
    CSingleton* ps2 = CSingleton::GetInstance(); 
    CSingleton* ps3 = ps1->GetInstance(); 
    CSingleton & ps4 = * CSingleton :: GetInstance();  
 
    if (ps1 == ps2) 
    { 
        cout<< "ps1 = ps2"<<endl; 
    } 
 
    if (ps1 == ps3) 
    { 
        cout<< "ps1 = ps3"<<endl; 
    } 
 
    if (&ps4 == ps1) 
    { 
        cout<< "ps1 = ps4"<<endl; 
    } 
 
    return 0; 

單例模式通過類本身來管理其唯一實例,唯一的實例是類的一個普通對象,但設計這個類時,讓它只能創建一個實例並提供對此實例的全局訪問。

用戶訪問唯一實例的方法只有 GetInstance() 成員函數。如果不通過這個函數,任何創建實例的嘗試都將失敗,因為類的構造函數是私有的。

有一點要注意:一定要加上 CSingleton* CSingleton::m_pInstance = NULL; 這一句,不然的話編譯會出錯,因為這一句才是變量定義。

二.單例類CSingleton 有以下特征 www.2cto.com

它有一個指向唯一實例的靜態指針m_pInstance,並且是私有的;

它有一個公有的函數,可以獲取這個唯一的實例,並且在需要的時候創建該實例;

它的構造函數是私有的,這樣就不能從別處創建該類的實例。

三.存在的問題

1.m_pInstance 指向的空間什麼時候釋放呢?

如果在類的析構行為中有必須的操作,比如關閉文件,釋放外部資源,那麼上面的代碼無法實現這個要求。我們需要一種方法,正常的刪除該實例。


不合理的解決方法:

在程序結束時調用 GetInstance(),並對返回的指針掉用 delete操作。這樣做可以實現功能,但不僅很丑陋,而且容易出錯。因為這樣的附加代碼很容易被忘記,而且也很難保證在delete之後,沒有代碼再調用 GetInstance 函數。也就是說釋放操作由使用者來管理,而不是由類本身來管理,這違背了類的單一職責的原則,這是不合理的。

2. 該實例的析構函數什麼時候執行?

上面的類裡為什麼沒有析構函數,其實即便你加上析構函數也是可以的,但是這個析構函數不會被執行的。因為你的實例是 new 出來的,所以只有 delete 時,才會調用析構函數,但是在哪裡調用 delete 呢!?這又回到了上面的問題。

一種妥善的方法:


[cpp]
class CSingleton 

public: 
    static CSingleton* GetInstance() 
    { 
        static CSingleton instance; //靜態局部變量 
         
        return &instance; 
    } 
 
private: 
 
    CSingleton() {}; //構造函數 
 
}; 
局部靜態對象實例 instance 是第一次調用 GetInstance() 時被構造,一直保持活動狀態直到應用程序終止,與動態分配對象不同,靜態對象當應用程序終止時被自動銷毀掉,所以就不必再手動銷毀實例了。
當然這裡,可以加上析構函數來處理你想要的操作。

這樣做的要點有以下幾點:

1. 靜態變量在內存中只有一份,從而保證了單例模式中單一實例的要求。

2. 靜態變量在程序終止時會被自動銷毀,從而保證了空間正常釋放。

 

作者 lwbeyond

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved