C++ 基类如何禁用派生类';s构造函数
我尝试编写一个单例类,这样一个类只需从中派生并自动成为单例: 基类:C++ 基类如何禁用派生类';s构造函数,c++,templates,inheritance,singleton,C++,Templates,Inheritance,Singleton,我尝试编写一个单例类,这样一个类只需从中派生并自动成为单例: 基类: template <class T> class Singleton { private: static T* instance; public: static T* getInstance(void) { if(!instance) instance = new T; return instance;
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;
这工作得很好,但它不是真正的单例,因为我仍然可以使用MySingleton的默认构造函数来构造它。当然,我可以将MySingleton的CTOR设置为私有,并将Singleton声明为朋友,但在基类中是否有任何方法可以做到这一点,以便仅派生和不声明任何CTOR就足以使类成为Singleton?因为基类模板必须构造Singleton对象,它需要访问具体类的构造函数。因此,构造函数应该是公共的,或者基类必须是具体类的朋友。每个人都可以访问具体类中的公共构造函数,因此不能禁止在编译时使用它。 但是,您可以确保在运行时只调用一次:
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;
模板
单件阶级
{
/* ... */
静态布尔实例化;
受保护的:
Singleton()
{
if(!实例化)//未在instance()函数中调用
抛出std::runtime_错误(“不要打电话给我!”);
}
公众:
静态T*getInstance()
{
暗示=真实;
instace=newt();
实例化=假;
}
};
模板
bool Singleton::实例化=false;
注:
-我在这里使用的实例化变量不是线程安全的
-实例化
的真/假设置也不例外安全(新建
或T::T()
可能抛出)
-使用指针作为实例变量是不安全的,并且容易发生memleaks。考虑使用<代码> SydDypPTR <代码>或引用(Meyers singleton),这是因为您可以使用Basic的构造函数:是的,我可以声明SuntLon私有的CtoR,但是编译器在“新T”中出错。当然,MySingleton的构建也不可能,所以我非常希望这个解决方案,如果它能够编译:)是的,我也这么认为,应该有一种方法可以解决这个问题(我也已经把它放到问题中了:))那就是我在再次发帖之前无法正确阅读东西:我想你要找的单词是受保护的
int main(int argc, const char * argv[])
{
MySingleton* s = MySingleton::getInstance();
s->helloWorld();
return 0;
}
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;