模板化的单例实现

在系统的代码中,我们有许多单例。

从[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的时候多了判断。 小问题,可以通过模板特化来实现。

posted @ 2015-09-26 20:14  westfly  阅读(822)  评论(0编辑  收藏  举报