2013-01-10 51 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

相关问题