2013-01-10 195 views
0

我嘗試寫一個單例類,這樣一類只需要從中得到和自動單:基類如何可以禁用派生類的構造函數

基類:

template <class T> 
class Singleton 
{ 
private: 
    static T* instance; 
public: 

    static T* getInstance(void) 
    { 
     if(!instance) 
      instance = new T; 
     return instance; 
    } 

    static void release(void) 
    { 
     if(instance) 
     { 
      delete instance; 
      instance = NULL; 
     } 
    } 
}; 

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

我派生類:

#include <iostream> 
#include "Singleton.h" 

class MySingleton : public Singleton<MySingleton> 
{ 
public: 
    void helloWorld(void) 
    { 
     printf("Hello, World!\n"); 
    } 
}; 

主:

int main(int argc, const char * argv[]) 
{ 
    MySingleton* s = MySingleton::getInstance(); 
    s->helloWorld(); 
    return 0; 
} 

這很好,但它不是一個真正的單身人士,因爲我仍然可以使用它的默認構造函數構造MySingleton。當然,我可以將MySingleton的ctors私有化,並將Singleton聲明爲朋友,但是我有什麼辦法可以在基類中做到這一點,所以只需派生並且不聲明任何ctors就足以構成一個類Singleton?

+0

這源於你可以使用基的構造函數的事實:http://liveworkspace.org/code/3iuwiB%242 – chris

+0

是的,我可以聲明Singleton私有的ctor ,但是編譯器在「new T」出錯。當然,MySingleton的構建也是不可能的,所以我很喜歡這個解決方案,如果它會編譯:) – Pontomedon

+0

是的,我也這麼認爲,應該有一種方法,除此之外(我也已經把它放到了問題中:)) – Pontomedon

回答

1

由於您的基類模板必須構造單例對象,因此它需要訪問具體類的構造函數。因此,構造函數應該是公共的,或者基類必須是具體類的朋友。每個人都可以訪問具體類中的公共Ctor,所以你不能在編譯時禁止它的使用。 你可以,但是,保證,它只是調用一次,在運行時:

template <class T> 
class Singleton 
{ 
    /* ... */ 
    static bool instantiating; 
protected: 
    Singleton() 
    { 
    if (!instantiating) //not called in instance() function 
     throw std::runtime_error("Don't call me!"); 
    } 

public: 
    static T* getInstance() 
    { 
    intantiating = true; 
    instace = new T(); 
    instantiating = false; 
    } 
}; 

template <class T> 
bool Singleton<T>::instantiating = false; 

注: - 該instantiating變量,因爲我在這裏使用它不是線程安全的 - 的instantiating真/假設置不是例外(newT::T()可能會拋出) - 您使用指針作爲實例變量不安全,容易產生內存泄露。考慮使用shared_ptr或參考(邁爾斯單身人士)

+0

感謝您的澄清! – Pontomedon

相關問題