Skip to content

Instantly share code, notes, and snippets.

@superlayone
Last active August 29, 2015 14:02
Show Gist options
  • Select an option

  • Save superlayone/4885519326efc6d2d16a to your computer and use it in GitHub Desktop.

Select an option

Save superlayone/4885519326efc6d2d16a to your computer and use it in GitHub Desktop.
C++ Singleton II

C++ Singleton

前一段时间面试豌豆荚的一道题,今天参见网上的一些博客,加上自己的理解写了一个觉得比较符合面试官当时意愿的Singleton

1. Singleton模板

Singleton.h 采用模板机制,使用产生确定类型的singleton类。 顺便说一下比较混淆的类模板和模板类。类模板首先是模板,用于产生类;而模板类是由这些类模板产生的类。比如:

        template <typename T> 
        class vector 
        { 
            … 
        }; 

就是一个类模板,而像vector <int>,vector <bool>等就是模板类。那么这个singleton是什么你就懂得了,(^__^) ...

        #include <memory>
        #include <iostream>
        #include "Lock.h"
        using namespace std;
        
        template <class T>
        class Singleton
        {
        public:
        	static inline T* Instance();
        private:
        	Singleton(){}
        	~Singleton(){}
        	Singleton(const Singleton&){}
        	Singleton & operator= (const Singleton &){}
        
        	static auto_ptr<T> _instance;
        	static Lockdown  _lk;
        };
        
        template <class T>
        //Initialise,point to nothing
        auto_ptr<T> Singleton<T>::_instance;
        
        template <class T>
        Lockdown  Singleton<T>::_lk;
        
        template <class T>
        inline T* Singleton<T>::Instance()
        {
        	if(NULL == _instance.get())
        	{
        		Lockdown::Nested ld(_lk);
        		if(NULL == _instance.get())
        		{
        			_instance.reset(new T);
        		}
        	}
        	return _instance.get();
        }
        //Class that will implement the singleton mode,
        //must use the macro in it's delare file
        #define DECLARE_SINGLETON_CLASS( type ) \
               friend class auto_ptr< type >;\
               friend class Singleton< type >;

2. 多线程互斥

Lock.h

也可以使用BOOST库实现,使用mutex实现多线程互斥,在返回一个实例的判断之前锁定该线程。

        #include <Windows.h>
        // Instances of this class will be accessed by multiple threads.
        class Lockdown {
        public:
           Lockdown()  
           { 
        	   m_Cnt = 0; 
        	   InitializeCriticalSection(&m_cs); 
           }
           ~Lockdown() 
           { 
        	   DeleteCriticalSection(&m_cs); 
           }
         
           // IsGuarded is used for debugging
           bool IsGuarded() const 
           { 
        	   return(m_Cnt > 0); 
           }
        public:
           class Nested {
           public:
              Nested(Lockdown& ld) : m_ld(ld) { m_ld.Guard(); };
              ~Nested() { m_ld.Unguard(); }
         
           private:
              Lockdown& m_ld;
           };
         
        private:
           void Guard()   { EnterCriticalSection(&m_cs); m_Cnt++; }
           void Unguard() { m_Cnt--; LeaveCriticalSection(&m_cs); }
         
           // Guard/Unguard can only be accessed by the nested CGuard class.
           friend class Lockdown::Nested;
         
        private:
           CRITICAL_SECTION m_cs;
           long m_Cnt;   // # of EnterCriticalSection calls
        };

3. 测试代码

        Singleton.cpp
        
        #include <memory>
        #include "Singleton.h"
        #include <iostream>
        using namespace std;
        
        class TestSingleton
        {
        public:
        	void Run()
        	{
        		cout<<"I'm a singletoned class...haha"<<endl;
        		cout<<"This address is "<<this<<endl;
        	}
        private:
        	TestSingleton(){}
        	virtual ~ TestSingleton(){}
        	DECLARE_SINGLETON_CLASS(TestSingleton);
        };
        
        int main()
        {
        	TestSingleton *t = Singleton<TestSingleton>::Instance();
        	TestSingleton *p = Singleton<TestSingleton>::Instance();
        
        	cout<<"Address t="<<t<<endl;
        	cout<<"Address p="<<p<<endl;
        
        	t->Run();
        	p->Run();
        
        
        	system("pause");
        	return 0;
        }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment