⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 singleton.h

📁 loki库的源代码。loki库是以模板技术和面向对象技术为基础的c++类库。
💻 H
📖 第 1 页 / 共 2 页
字号:
			// the throw will yield a C1001-internal compiler error.
			// The new level of indirection solves the problem
			// throw std::logic_error("Dead Reference Detected");
			Thrower("Dead Reference Detected");	
		}
    };

////////////////////////////////////////////////////////////////////////////////
// class template PhoenixSingleton
// Implementation of the LifetimePolicy used by SingletonHolder
// Schedules an object's destruction as per C++ rules, and it allows object 
//    recreation by not throwing an exception from OnDeadReference
////////////////////////////////////////////////////////////////////////////////

    
    class PhoenixSingleton
    {
	private:
		template <class T>
		struct StaticData
		{
			static bool destroyedOnce_;
		};
	public:
        template <class T>
		static void ScheduleDestruction(T*, void (*pFun)())
        {
			
#ifndef ATEXIT_FIXED
            if (!StaticData<T>::destroyedOnce_)
#endif
                VC_BROKEN_STD::atexit(pFun);
        }
        
        template <class T>
		static void OnDeadReference(const volatile T* p = 0 )
        {
#ifndef ATEXIT_FIXED
            StaticData<T>::destroyedOnce_ = true;
			
#endif
        }
        
    };
#ifndef ATEXIT_FIXED
	template <class T> 
	bool ::Loki::PhoenixSingleton::StaticData<T>::destroyedOnce_ = false;
#endif


        
////////////////////////////////////////////////////////////////////////////////
// class template Adapter
// Helper for SingletonWithLongevity below
////////////////////////////////////////////////////////////////////////////////

    namespace Private
    {
        template <class T>
        struct Adapter
        {
            void operator()(T*) { pFun_(); return ; }
            void (*pFun_)();
        };
    }

////////////////////////////////////////////////////////////////////////////////
// class template SingletonWithLongevity
// Implementation of the LifetimePolicy used by SingletonHolder
// Schedules an object's destruction in order of their longevities
// Assumes a visible function GetLongevity(T*) that returns the longevity of the
//     object
////////////////////////////////////////////////////////////////////////////////
    
	class SingletonWithLongevity
    {
    public:
        template <class T>
		static void ScheduleDestruction(T* pObj, void (*pFun)())
        {
            Private::Adapter<T> adapter;
			adapter.pFun_ = pFun ;
            SetLongevity(pObj, GetLongevity(pObj), adapter);
        }
        
        template <class T>
		static void OnDeadReference(const volatile T* p = 0 )
        { 
			// the throw will yield a C1001-internal compiler error.
			// The new level of indirection solves the problem
			// throw std::logic_error("Dead Reference Detected");
			Thrower("Dead Reference Detected"); 
		}
    };

////////////////////////////////////////////////////////////////////////////////
// class template NoDestroy
// Implementation of the LifetimePolicy used by SingletonHolder
// Never destroys the object
////////////////////////////////////////////////////////////////////////////////

    
    struct NoDestroy
    {
        template <class T>
		static void ScheduleDestruction(T*, void (*)())
        {}
        
        template <class T>
		static void OnDeadReference(const volatile T* p = 0)
        {}
    };

////////////////////////////////////////////////////////////////////////////////
// class template SingletonHolder
// Provides Singleton amenities for a type T
// To protect that type from spurious instantiations, you have to protect it
//     yourself.
////////////////////////////////////////////////////////////////////////////////

    template
    <
        typename T,
        class CreationPolicy = CreateUsingNew,
        class LifetimePolicy = DefaultLifetime,
        class ThreadingModel = SingleThreaded
    >
    class SingletonHolder
    {
    public:
        static T& Instance();
        
    private:
        // Helpers
        static void MakeInstance();
        static void DestroySingleton();
        
        // Protection
        SingletonHolder();
        
        // Data
        typedef typename Apply1<ThreadingModel, T*>::VolatileType VolatileType;
		static VolatileType pInstance_;
        static bool destroyed_;
    };
    
////////////////////////////////////////////////////////////////////////////////
// SingletonHolder's data
////////////////////////////////////////////////////////////////////////////////

    template
    <
        class T,
        class C,
        class L,
        class M
    >
    typename SingletonHolder<T, C, L, M>::VolatileType
        SingletonHolder<T, C, L, M>::pInstance_;

    template
    <
        class T,
        class C,
        class L,
        class M
    >
    bool SingletonHolder<T, C, L, M>::destroyed_;

////////////////////////////////////////////////////////////////////////////////
// SingletonHolder::Instance
////////////////////////////////////////////////////////////////////////////////

    template
    <
        class T,
        class CreationPolicy,
        class LifetimePolicy,
        class ThreadingModel
    >
    inline T& SingletonHolder<T, CreationPolicy, 
        LifetimePolicy, ThreadingModel>::Instance()
    {
        if (!pInstance_)
        {
            MakeInstance();
        }
        return *pInstance_;
    }

////////////////////////////////////////////////////////////////////////////////
// SingletonHolder::MakeInstance (helper for Instance)
////////////////////////////////////////////////////////////////////////////////

    template
    <
        class T,
        class CreationPolicy,
        class LifetimePolicy,
        class ThreadingModel
    >
    void SingletonHolder<T, CreationPolicy, 
        LifetimePolicy, ThreadingModel>::MakeInstance()
    {
        //typename Apply1<ThreadingModel, T>::Lock guard;
		typename Apply1<ThreadingModel, SingletonHolder>::Lock guard;
        (void)guard;
        
        if (!pInstance_)
        {
            if (destroyed_)
            {
                LifetimePolicy::OnDeadReference(pInstance_);
                destroyed_ = false;
            }
            pInstance_ = CreationPolicy::Create(pInstance_);
            LifetimePolicy::ScheduleDestruction(pInstance_, 
                &DestroySingleton);
        }
    }

    template
    <
        class T,
        class CreationPolicy,
        class L,
        class M
    >
    void SingletonHolder<T, CreationPolicy, L, M>::DestroySingleton()
    {
        assert(!destroyed_);
        CreationPolicy::Destroy(pInstance_);
        pInstance_ = 0;
        destroyed_ = true;
    }
} // namespace Loki

////////////////////////////////////////////////////////////////////////////////
// Change log:
// May 21, 2001: Correct the volatile qualifier - credit due to Darin Adler
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
// Oct	06	2002: ported by Benjamin Kaufmann to MSVC 6.0
// Feb	24, 2003: changed parameter name of CreateUsingMalloc::Create, 
//					changed SingletonHolder::MakeInstance in accordance with 
//					Bug-report #691687 B.K.
////////////////////////////////////////////////////////////////////////////////

#endif // SINGLETON_INC_

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -