2012-01-23 92 views
0

我想討論着名的Singleton設計模式實現的細微差別。 在這裏有在C++兩種實現方式:Singleton類的實現版本

http://www.codeproject.com/Articles/1921/Singleton-Pattern-its-implementation-with-C

,另外一個是這樣的:

#ifndef __SINGLETON_HPP_ 
#define __SINGLETON_HPP_ 

template <class T> 
class Singleton 
{ 
public: 
    static T* Instance() { 
     if(!m_pInstance) m_pInstance = new T; 
     assert(m_pInstance !=NULL); 
     return m_pInstance; 
    } 
protected: 
    Singleton(); 
    ~Singleton(); 
private: 
    Singleton(Singleton const&); 
    Singleton& operator=(Singleton const&); 
    static T* m_pInstance; 
}; 

template <class T> T* Singleton<T>::m_pInstance=NULL; 

#endif 

如果我們比較這版本確實他們有什麼優勢和劣勢,最終,該版本是首選?

+0

是的,這是一種模式,但並不意味着你應該使用它。你會選擇兩個邪惡中的較小者。我不認爲你真的需要它。 –

+1

@PeterWood這不是一種模式 - 它是一種反模式 –

+2

你知道使用名爲'__SINGLETON_HPP_'的包括守衛除了醜陋外其實是錯誤的嗎? – 6502

回答

1

這兩種實現之間的主要差異之間的區別是:

  • 第一添加冗餘標誌,告訴你是否沒有指針爲空,因此佔用的內存略多於需要;
  • 第二個根本不是單身人士:沒有什麼可以阻止T擁有公共構造函數,從而打破單身人士的限制。

與兩者的主要問題(超出一個事實,即單是永遠擺在首位是個好主意)是:

  • 建設是不是線程安全的;從兩個線程調用Instance()可能會導致創建兩個對象;
  • 既有泄漏記憶;他們動態地創建與new對象,但從未呼籲delete

在C++中,安全地管理全局可訪問對象的生命期非常困難;出於這個原因(和many others),我會建議完全避免Singleton反模式。在管理良好的範圍中創建對象,並在需要時傳遞參考。

如果你真的想要一個全局可訪問的實例,那麼在大多數情況下,最簡單,最安全的選擇是:

static Singleton & Instance() { 
    static Singleton instance; 
    return instance; 
} 

這將創建第一次函數被調用,以及C++ 11編譯器必須確保這是線程安全的。剩下的問題是,實例可能會在其他靜態對象之前被銷燬,如果它們的析構函數嘗試訪問它,則會造成災難。

0

基本上,兩個實現都是一樣的。在CodeProject上實現提供了兩件事情:

  • 單身狀態標誌,它允許您標記單作爲「老」從外面(然後正確地從內重新實例吧)
  • getInstance方法,這是沒有什麼特別的,從單的透視。然而,這會使得代碼在一段時間後對其他人和你自己更易讀。

只是
Cat::meow();
Cat::getInstance()->meow()