C 實現單例的5種方法總結

2021-07-26 09:08:45 字數 3687 閱讀 2979

本文結合一些已有的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,它充當資料儲...