单例模板类






3.29/5 (21投票s)
2003年3月20日
2分钟阅读

156242

2036
单例模板类
引言
有些时候,你需要一个只能被实例化一次的类。单例设计模式为此提供了一个解决方案。
有几种可能的实现单例模式的方法,但归根结底,都是一个具有私有构造函数和静态成员函数来创建和检索类实例的类。我的实现与此场景没有太大区别,唯一的例外是我创建了一个单例模板类。
那么,为什么是模板类呢?
嗯,我在互联网上搜索了一个优雅的单例类实现,但并没有找到令我满意的解决方案。我找到的大多数类都包含一个Singleton
基类,你可以从中派生你自己的单例类。这些类中的大多数问题在于,你仍然需要重写GetInstance
函数以返回指向你的派生类的指针。模板基类没有这个限制,因为我可以返回任何类型的指针。
工作原理
为了防止外部源创建(或复制)我们的单例类的实例,我们需要屏蔽单例类的构造函数和复制构造函数。此外,我们需要提供一个方法来创建和检索对单例对象的引用。
static T* Instance()
{
if (m_instance == NULL) m_instance = new T;
ASSERT(m_instance != NULL);
return m_instance;
};
当第一次调用此方法时,它会创建单例类的实例,任何后续调用都将返回对已创建类实例的引用。要获取对单例对象的引用,我们只需要按以下方式调用此方法:
CMySingleton* mySingleton = CMySingleton::Instance();
这几乎就是它的全部。除了屏蔽构造函数之外,我还屏蔽了析构函数,因此单例类不会被意外删除。只需调用DestroyInstance()
方法即可销毁单例对象。但是,请小心何时调用此方法,因为在调用此方法之后,你的所有类数据都将被销毁,并且后续对Instance()
方法的调用将创建一个新的实例。
那么,如何创建一个从单例模板类派生的类呢? 同样,这很简单。只需包含附带的头文件,并按以下方式创建你的对象:
class CMySingleton : public CSingleton<CMySingleton>
{
friend CSingleton<CMySingleton>;
private:
CMySingleton();
~CMySingleton();
...
}
结论
这种单例模式的实现使得创建你自己的单例类变得非常容易。但是,你必须小心何时销毁单例类实例。如果你发现这是一个问题,你可以考虑添加(自动)引用计数。