小窥模板元编程

Singleton 的C++实现

皮贝贝 posted @ 2008年8月23日 18:07 in 模式之灾 with tags c++ 单件 单件模式 , 2873 阅读

 

一、GoF描述: 
      “保证一个class 只有一个实体(instance),并为它提供一个全局访问点(global
access point)”。

        可以看出Singleton的几个特性:@一个Singleton对象负责自身的诞生和摧毁,外部对象
无法另外构造和摧毁一个Singleton对象,因为这些属于Singleton对象的内部工作了。@一个
Singleton对象提供了一个统一的外部接口,外部只能通过此来获取并使用该Singleton对
象。

二、现实世界里的Singleton 
       Singleton是存在最广泛的一种模式。
       可以是资源配置,可以是数据库连接。差不多都是出于效率和管理集中方便两方面考虑。
   
三、框架实现 
        先根据描述来给出一个框架,有一个Instance()接口来向外界提供对象。再次,让外界无
法自己构建和析构,所以设构造函数、析构函数等不为用户所用的为私有。  

  1.         template <class Type>
  2.         class Singleton
  3.         {
  4.         public:
  5.                 static Type* Instance();
  6.  
  7.         private:
  8.                 Singleton(){}
  9.                 ~Singleton(){}
  10.                 Singleton& operator = ( const Singleton& ){}
  11.         };
  12.  

        当然要设计成为单件的类也要遵循自我构建性,即不允许用户构建摧毁,所以应设这些函数
为私有。要使其正常工作,必须让我们的|Singleton|模板可以构建摧毁。这就要设为友元了,
在类内部必须有这样一句( 假使类名为A ): 

  1.         friend class Singleton <A>;

       这样类A的声明如下:

  1.         class A
  2.         {
  3.         public:
  4.                 // 提供给用户使用的一些方法
  5.         private:
  6.                 A();
  7.                 ~A();
  8.                 A& operator = ( const A& );
  9.         };
  10.  
  11.         typedef Singleton <A> SA;

       这样,我们在使用A的时候,像下面一样: 

  1.         SA::Instance()->方法();

四、具化Singleton 
      你可以用 static 静态类来实现内部对象管理,但是static有诸多不妙之处,所以我
用了指针管理,指针来管理对象的构建销毁,自然就用 std提供的 auto_ptr 了。
  为了实现多线程的对象安全性构建,封装了下面一个锁类,利用windows的关键区机制:

  1. ////////////////////////////////////////////////////////////////////////////////
  2. //      类名:     SingleThreadModal
  3. //      功能:     单线程模型
  4. //      实现:     空内容以兼容线程接口
  5. ////////////////////////////////////////////////////////////////////////////////
  6. class SingleThreadModal
  7. {
  8. public:
  9.         class Lock
  10.         {
  11.         public:
  12.                 Lock(){}
  13.                 Lock( SingleThreadModal& ) {}
  14.         };
  15. };
  16.  
  17. ////////////////////////////////////////////////////////////////////////////////
  18. //      类名:     MultiThreadModal
  19. //      功能:     多线程模型
  20. //            处理数据安全,
  21. //      实现:     以windows关键区加锁与解锁实现
  22. ////////////////////////////////////////////////////////////////////////////////
  23. class MultiThreadModal
  24. {
  25. public:
  26.         MultiThreadModal();
  27.         ~MultiThreadModal();
  28.  
  29.         class Lock
  30.         {
  31.                 MultiThreadModal& m_Host;
  32.         public:
  33.                 //Lock() {}
  34.                 Lock( MultiThreadModal& Host )
  35.                         : m_Host( Host )
  36.                 {
  37.                         m_Host.Guard();
  38.                 }
  39.                 ~Lock()
  40.                 {
  41.                         m_Host.UnGuard();
  42.                 }
  43.         };
  44.  
  45. protected:
  46.         void Guard();
  47.         void UnGuard();
  48. private:
  49.         CRITICAL_SECTION m_cs;
  50. };

        使用一个内嵌类,主要是为了防止用户的结对编程的考虑不足,就像new和delete一
样,很多时候我们忘记了delete,这里用内嵌类也是出于此考虑,把解锁工作由C++
的语言机制来自动处理,这里用的是C++的生命期控制。
        另外,提供一个空壳的 SingleThreadModal 是为了接口统一。

  所以我们的 Singleton 可以实现了:

  1.         //------------------------------------------------------------------------------
  2.         //      宏名:     DECLARE_SINGLETON_CLASS                单线程单件模型声明
  3.         //            DECLARE_SINGLETON_CLASS_MT        多线程单件模型声明
  4.         //------------------------------------------------------------------------------
  5.         #define DECLARE_SINGLETON_CLASS( Type )  \
  6.                 friend class std::auto_ptr <Type>;            \
  7.                 friend class Singleton <Type, SingleThreadModal>;
  8.  
  9.         #define DECLARE_SINGLETON_CLASS_MT( Type )       \
  10.                 friend class std::auto_ptr <Type>;      \
  11.                 friend class Singleton <Type, MultiThreadModal>;
  12.  
  13.         ////////////////////////////////////////////////////////////////////////////////
  14.         //      类名:     Singleton
  15.         //      功能:     单件
  16.         //      参数:     Type------型别
  17.         //            ThreadModal-----单线程或多线程选择,
  18.         ////////////////////////////////////////////////////////////////////////////////
  19.  
  20.         template <class Type,
  21.                  class ThreadModal = SingleThreadModal>
  22.         class Singleton
  23.         {
  24.         public:
  25.                 static inline Type* Instance();
  26.  
  27.         private:
  28.                 static ThreadModal                  m_Thread;               // 线程
  29.                 static std::auto_ptr <Type>          m_pObj;
  30.         };
  31.  
  32.         //------------------------------------------------------------------------------
  33.         //      Singleton 数据成员
  34.         //------------------------------------------------------------------------------
  35.         template <class Type, class ThreadModal>
  36.         ThreadModal                    Singleton <Type, ThreadModal> ::m_Thread;
  37.  
  38.         template <class Type, class ThreadModal>
  39.         typename std::auto_ptr <Type>  
  40.                                                 Singleton <Type, ThreadModal> ::m_pObj;
  41.  
  42.  
  43.         //------------------------------------------------------------------------------
  44.         //      Singleton 成员函数
  45.         //------------------------------------------------------------------------------
  46.         template <class Type, class ThreadModal>
  47.         inline Type* Singleton <Type, ThreadModal> ::Instance()
  48.         {
  49.                 if ( 0 == m_pObj.get() )
  50.                 {
  51.                         typename ThreadModal::Lock      Guard( m_Thread );
  52.                         if ( 0 == m_pObj.get() )
  53.                         {
  54.                                 m_pObj.reset( new Type() );
  55.                         }
  56.                 }
  57.                 return m_pObj.get();
  58.         }
  59.  

       值得一提的是,在 Instance() 的实现体重,采用了双检测模式,主要是为了加锁与
解锁只是在第一次尚未构建的情况下发生,构建完成后,其此时所有在检测中中断的线程都
完成后,以后所有的线程要想获得对象就不必再用锁管理了。
      当然假如了线程管理,框架比前所述的框架多了点东西(这点微不足道的东西让我们更
心里踏实).

五、设计改进 
         当然这只是一个可以正常工作,并且在大多数情况下,这已经足够了。要想设计一个完整的
符合所有情况的,还要从 生命期管理的角度添加策略了。
 

Avatar_small
pavzi. com 说:
2024年1月09日 19:52

The primary idea or goal of this website has been to offer resources that contain comprehensive information on every subject and are accessible via the Internet. making certain that each and every reader finds the most relevant and pavzi.com worthwhile information regarding the subject they are searching for and linking to our content.Because our website is multi-niche or multi-category, it will guarantee that it offers resources and information on every subject. Our website features a number of timeless topics, including career, job recruitment, education, technology, and reviews, among others. Indeed, Tech, Finance, and Product Reviews are our primary focus.

Avatar_small
boardmodelpaper. co 说:
2024年1月09日 20:22

A sample or model question paper created by educational boards or other institutions for a variety of exams is commonly referred to as the Board model paper. These practice papers give students a sense of the format, degree of difficulty, and kind of material that may be covered in the real exam, helping them get ready for exams. Typically, model papers are written for particular courses or subjects. They cover boardmodelpaper.com a variety of subjects and chapters that are anticipated to have been studied by students during the course of the semester.


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter