2016-09-22 32 views
-2

其用途是提供.instance訪問權限,以防止這些類別的重複對象。防止使用單例訪問類/實例中的重複對象

這是一個很好的單例代碼實現嗎?

template <typename T> class singleton 
{ 
public: 
    static T *ms_singleton; 

    singleton() 
    { 
     assert(!ms_singleton); 
     long offset = (long)(T *) 1 - (long)(singleton <T> *)(T *) 1; 
     ms_singleton = (T *)((long) this + offset); 
    } 

    virtual ~singleton() 
    { 
     assert(ms_singleton); 
     ms_singleton = 0; 
    } 

    static T &instance() 
    { 
     assert(ms_singleton); 
     return (*ms_singleton); 
    } 

    static T &Instance() 
    { 
     assert(ms_singleton); 
     return (*ms_singleton); 
    } 

    static T *instance_ptr() 
    { 
     return (ms_singleton); 
    } 
}; 
template <typename T> T *singleton <T>::ms_singleton = NULL; 

我如何使用它:

class test1: public singleton<test2> 
{ 
    // Something 
}; 

如果不是,這裏有什麼問題?我應該在這裏重寫什麼?

+2

如果真的是你想要的單身爲什麼不使用邁爾斯的辛格爾頓。 – Jarod42

+1

這不是一個單身人士,因爲你有一個公共構造函數。 – NathanOliver

+0

而你的偏移量計算很奇怪......你想完成什麼? – Jarod42

回答

1

你的單身人士有一些奇怪的事情。就像你依靠構造函數來執行調試構建運行時檢查它是否可以構建或在你的構造函數中一樣。

一個典型的單例類具有私有的構造函數,所以它只能由訪問函數構造。它也不應該依賴於例如assert這是一個在發佈版本中被禁用的宏。

一個簡單的非遺傳的單例類看起來是這樣的:

class Singleton 
{ 
public: 
    static Singleton& instance() 
    { 
     static Singleton actual_instance; 
     return actual_instance; 
    } 

    // Other public member functions 

private: 
    // Private constructor 
    Singleton() = default; 
}; 

通過具有構造私有的,這意味着沒有其他人不能試圖建構一個實例。這也意味着這是在編譯器自己編譯時檢查的。

此外,通過將對象的實際實例作爲靜態變量在訪問器函數內的定義處初始化,意味着創建實例是線程安全的。


爲了擴大它,讓它像普通的你似乎想要做的,那麼你就需要讓基類構造函數的保護。您還需要在繼承的類中創建基類friend

孩子類仍需要使其構造函數專用以防止意外構造。

更新,則基類看起來像

template<typename T> 
class Singleton 
{ 
public: 
    static T& instance() 
    { 
     static T actual_instance; 
     return actual_instance; 
    } 

protected: 
    Singleton() = default; 
}; 

子類可能看起來像

class ChildSingleton : public Singleton<ChildSingleton> 
{ 
public: 
    // Public member functions... 

private: 
    friend class Singleton<ChildSingleton>; 

    // Private constructor 
    ChildSingleton() = default; 
}; 
+0

是否有任何理由使用'靜態單身人士* actual_instance = new Singleton;'over'static Singleton actual_instance;'? – NathanOliver

+0

@NathanOliver不是真的沒有,可能與我的思想有些問題。 –

+0

看看鏗鏘3.4說http://prntscr.com/cl331l – Smartx221