模板化的单例实现
在系统的代码中,我们有许多单例。
从[cegui](http://cegui.org.uk/) 的代码中的找到一个基于模板的类,具体代码改变后如下
#ifndef _SINGLETON_H_ #define _SINGLETON_H_ #include <cassert> #include <stdio.h> template <typename T> class Singleton { protected: static T* m_inst_; public: Singleton() { assert( !m_inst_ ); m_inst_ = static_cast<T*>(this); } ~Singleton() { assert( m_inst_ ); m_inst_ = 0; } static T* instance() { return ( m_inst_ ); } private: Singleton& operator=(const Singleton&); Singleton(const Singleton&); }; template <typename T> T* Singleton<T>::m_inst_ = NULL;
这个类的使用情况是基于栈上的分配的,作为全局的变量。 我一直用得挺好的。直到到我遇到了有依赖的全局变量,在一个单例中,调用另外一个单例, 可能因为声明顺序问题,引起单例得到的为空。
而且这种实现,与系统中的在堆上分配内存不符合,当遇到大对象时,不得不在堆上分配,使用受限。
于是灵光一现,添加了一个默认参数,出现了如下的模板实现
template <typename T, bool heap_alloc = true> class Singleton { protected: static T* m_inst_; public: Singleton() { if (!heap_alloc) { assert( !m_inst_ ); m_inst_ = static_cast<T*>(this); } } ~Singleton() { assert( m_inst_ ); m_inst_ = 0; } static T* instance() { if (heap_alloc && !m_inst_) { m_inst_ = new T(); } return ( m_inst_ ); } private: Singleton& operator=(const Singleton&); Singleton(const Singleton&); }; template <typename T, bool heap_alloc> T* Singleton<T, heap_alloc>::m_inst_ = NULL;
这样就会在不影响实现的情况下,默认情况下就会在堆上分配,但因为每次instance的时候多了判断。 小问题,可以通过模板特化来实现。