两种Singleton的设计方法

两种Singleton的设计方法
分析一下两种我觉得不错的Singleton设计

第一种写法,符合gof规范

 1  template < class  T >
 2  class  Singleton
 3  {
 4  // Constructors
 5  protected :
 6      Singleton(){};
 7      Singleton( const  Singleton  & ){};
 8       virtual   ~ Singleton(){};
 9 
10  // Operators
11  private :
12       // disable "=" operator
13      Singleton  & operator = ( const  Singleton  & );
14 
15  // Methods
16  public :
17       // Lazy initialize
18       static  inline T  & Instance()
19      {
20           return   * InstancePtr();
21      }
22 
23       // Lazy initialize
24       static  inline T  * InstancePtr()
25      {
26           if ( NULL  ==  m_instPtr )
27          {
28              pthread_mutex_t m_mutex;
29              pthread_mutex_init( & m_mutex, NULL);
30              pthread_mutex_lock( & m_mutex);
31 
32               if ( NULL  ==  m_instPtr )
33                  m_instPtr = new  T();
34 
35              pthread_mutex_unlock( & m_mutex);
36              pthread_mutex_destroy( & m_mutex);
37          }
38 
39           return  m_instPtr;
40      }
41 
42  // Members
43  protected :
44       static  SmartPtr < T >  m_instPtr;
45  };
46 
47  template < class  T >
48  SmartPtr < T >  Singleton < T > ::m_instPtr  =  NULL;

SmartPtr是我自己实现的一个智能指针,实例化对象的时候,使用pthread同步。
优点:这种写法易于使用,只需要继承一个Singleton<T>,就可以了,不会产生冗余代码
缺点:1.继承Singleton的类不可被子类继承,否则Instance()错误
      2.继承Singleton的类必须显示提供一个无参数的默认构造函数

其实这种写法往往不易于实际项目使用,缺点2是其致命点。因为提供一个默认构造函数意味着构造出的对象是不可立即使用的,还要initialize,这就不得不再去写initialize函数,并且必须通知使用者调用initialize方法。另外,缺点1可以通过一个多继承模式来解决。
如:A类需要Singleton,则创建一个ABase类,让A派生于ABase和Singleton,而A的子类可以派生于ABase,这样就不会造成Singleton冲突


再来看一下Ogre中的Singleton:
 1   template  < typename T >   class  Singleton
 2      {
 3       private :
 4           /* * \brief Explicit private copy constructor. This is a forbidden operation. */
 5          Singleton( const  Singleton < T >   & );
 6 
 7           /* * \brief Private operator= . This is a forbidden operation.  */
 8          Singleton &   operator = ( const  Singleton < T >   & );
 9      
10       protected :
11 
12           static  T *  ms_Singleton;
13 
14       public :
15          Singleton(  void  )
16          {
17              assert(  ! ms_Singleton );
18  #if  defined( _MSC_VER ) && _MSC_VER < 1200     
19               int  offset  =  ( int )(T * ) 1   -  ( int )(Singleton  < T >* )(T * ) 1 ;
20              ms_Singleton  =  (T * )(( int ) this   +  offset);
21  #else
22          ms_Singleton  =  static_cast <  T *   > this  );
23  #endif
24          }
25           ~ Singleton(  void  )
26              {  assert( ms_Singleton );  ms_Singleton  =   0 ;  }
27           static  T &  getSingleton(  void  )
28          {    assert( ms_Singleton );   return  (  * ms_Singleton ); }
29           static  T *  getSingletonPtr(  void  )
30          {  return  ms_Singleton; }
31      };

优点:Ogre的Singleton可以通过让用户自定义getSingleton()函数,来避免前一种Singleton模式的两个缺点
缺点:不易使用,每一个继承自Singleton的类,用户必须为其编写getSingleton的代码,并且必须显示实例化一次这个类,才能使用Singleton


Ogre的这种Singleton的缺点其实可以通过宏定义来节省很多事,实际的项目应用中,这种写法更适合使用

你可能感兴趣的:(两种Singleton的设计方法)