本文結合一些已有的c++ 單例模式 設計方法,總結出了5種實現方式,並指出其中的使用特點和注意事項;
++ 幾種單例模式的寫法
一般情況下,為了實現單例我們都會想到使用 static 成員,下面#1是最基本的方式;
#1 靜態指標成員:
class singleton;
virtual ~singleton(){};
public:
singleton *instance();
protect:
static singleton *_instance;
};
singleton *singleton::instance()
return _instance;
}
構造時機: 執行時生成;
物件位置: 堆
資源釋放: new的單例物件,沒有時機去釋放;
執行緒安全: 否; ---在單例構造過程可能重複,造成記憶體洩露;
#2 靜態指標成員(改進型):
在#1的基礎上解決存在的兩個問題;
如果單例物件的構造實在執行時之前(也就是程式靜態變數初始化時完成)就可以避免執行緒安全的問題;
class singleton;
singleton& operator=(const singleton&){};
private:
class cgarbo
}
};
private:
static singleton *m_pinstance;
static cgarbo garbo;
};
singleton::cgarbo singleton::garbo;
singleton* singleton::m_pinstance = new singleton();
singleton::singleton()
singleton::~singleton()
singleton* singleton::instance()
構造時機: 初始化時生成;
物件位置: 堆
資源釋放: 通過乙個成員的析構函式來釋放單例物件,; 非常巧妙, 但是m_pinstance指標和 garbo兩個成員的析構是否有先後順序,如果指標先被釋放(指標變數變成null?)那麼單例物件還是沒有機會被釋放; ---找時間確認一下,然後更新一下這個結果;
執行緒安全: 是; ---初始化過程,沒有執行緒競爭;
對比以上兩種方式,可以看出靜態初始化的時候構造單例物件,能夠比較好的解決執行緒安全的問題; 但是資源釋放的需要通過曲線救國的方式來解決;
那麼能不能把單例物件也生成在靜態區呢?這樣釋放的問題就可以由作業系統自動完成;
#3 靜態成員物件
class singleton;
singleton& operator=(const singleton&){};
private:
static singleton m_instance;
};
singleton singleton::m_instance;
singleton::singleton()
singleton::~singleton()
singleton *singleton::instance()
構造時機: 初始化時生成;
物件位置: 靜態區
資源釋放: 在程式結束時 自動釋放靜態區的 成員變數
執行緒安全: 是;
注意: 靜態成員的初始化需要放到類外完成; 那麼是否可以把靜態物件在成員函式instance()內部生成呢?
#4 靜態區域性物件
class singleton;
singleton& operator=(const singleton&){};
};
singleton::singleton()
singleton::~singleton()
singleton *singleton::instance()
物件位置: 靜態區
資源釋放: 在程式結束時 自動釋放靜態區的 成員變數
綜合以上4中方式,單例物件的釋放都是在程式結束時釋放,
如果要求能夠提供介面隨時釋放物件,那麼就必須構造在堆上,然後提供顯式的destroy介面;
#5 靜態指標成員(動態釋放)
#ifndef __mutex_h__
#define __mutex_h__
#include class mutex;
mutex& operator=(const mutex&){};
public:
int lock();
int unlock();
int trylock();
};
#endif //__mutex_h__
#include "mutex.h"
mutex::mutex()
mutex::~mutex()
int mutex::lock()
int mutex::unlock()
int mutex::trylock()
//單例類
#ifndef __singleton_h__
#defile __singleton_h__
#include "mutex.h"
class singleton;
singleton& operator=(const singleton&){};
private:
static singleton *m_pinstance;
static mutex m_mutex;
};
#endif //__singleton_h__
singleton* singleton::m_pinstance = null;
mutex singleton::m_mutex;
singleton::singleton()
singleton::~singleton()
singleton* singleton::instance()
m_mutex.unlock();
} return m_pinstance;
} void singleton::destroy()
m_mutex.unlock();
} }
當然 也可以吧 靜態成員指標放到介面函式裡面作為區域性靜態變數 和區域性靜態物件;
實現單例模式的五種方法
二 懶漢式 懶漢式與餓漢式的區別 餓漢模式的特點是載入類時比較慢,但執行時獲取物件的速度比較快 執行緒安全 懶漢模式的特點是載入類時比較快,但執行時獲取物件的速度比較慢 執行緒不安全 三 第三種也叫雙重鎖檢測 這個模式將同步內容放到if內部,提高了執行的效率,不必每次獲取物件時都進行同步,只有第一次...
單例模式實現的五種方法
測試餓漢式單例模式 author carlosxu public class hungrysingleton 方法不用同步,呼叫效率高 public hungrysingleton getinstance 測試懶漢式單例模式 author carlosxu public class lazysing...
七種方法實現單例模式
三 懶漢式應用例項 四 雙重檢查 推薦使用 五 靜態內部類 推薦使用 六 列舉 推薦使用 所謂類的單例設計模式,就是採取一定的方法保證在整個的軟體系統中,對某個類只能存在乙個物件例項,並且該類只提供乙個取得其物件例項的方法 靜態方法 比如hibernate的sessionfactory,它充當資料儲...