zoukankan      html  css  js  c++  java
  • 模板化的单例实现

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

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

  • 相关阅读:
    VUE的生命周期
    ID生成算法(二)
    ID生成算法(一)——雪花算法
    HTTP状态码和支持的方法
    水平居中/垂直居中/水平垂直居中总结
    判断数组类型的4种方法
    WebSocket浅谈
    vue中使用定时器时this指向
    银行转账业务梳理
    支付那些事儿
  • 原文地址:https://www.cnblogs.com/westfly/p/4841223.html
Copyright © 2011-2022 走看看