我尝试编写一个单例类,以便一个类仅需要从其派生并自动为单例:
基类:
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的ctor设为私有,并声明Singleton为朋友,但是我可以在基类中做到这一点吗,因此仅派生而不声明任何ctor足以使一个类singleton足够?
最佳答案
由于您的基类模板必须构造单例对象,因此需要访问具体类的构造函数。因此,该构造函数应该是公共的,或者基类必须是具体类的朋友。每个人都可以访问具体类中的公共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
的true / false设置不是异常安全的(new
或T::T()
可能抛出)-您将指针用作实例变量是不安全的,并且容易出现记忆缺陷。考虑使用
shared_ptr
或参考(迈耶单例)关于c++ - 基类如何禁用派生类的构造函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14256429/