一个单件基类的实现

引子
        当我们在程序里只需生成类的一个实例时,我们通常会把这个类设计成单件类以保证程序最多只能生成这个类的一个实例。 于是乎如果我们的程序是个比较庞大的系统,而这个程序里头的许多个类都需要设计成单件类时,就会有很多重复的代码。恩,单件类毕竟有很多类似的地方,所以我们可以生成一个单件基类,其它的具体单件类都从这个基类继承。

基本思想
        把所有的单件类的实例都存放于单件基类的一个哈希表中,程序中需要用到某个具体单件类的实例时就从这个表中查找。

实现
        首先我们定义一些宏:
        #define MAX_CLASSNAMELEN    30  // 单件子类名称的最大长度
        #define HASHMAPSIZE      10       // 哈希表长度

       // 宣告一个单件类宏,classname为子类名称,param为子类构造函数参数列表(可以为空)
       #define DECLARE_SINGLETON(classname , param)      /
                     public:                                                                              /
                            static classname* GetInstance();                       /
                            static void DestroyInstance();                               /
                     private:                                                                             /
                            classname(param);

       // 实现单件类的基本函数宏,classname为子类名称,param为子类构造函数参数列表(可以为空)
       #define IMPLEMENT_SINGLETON(classname , param)                                       /
                      classname* classname::GetInstance()                                                      /
                      {                                                                                                                           /
                             classname* pObj = (classname *)(FindInstance(#classname));  /
                             if( pObj == NULL )                                                                                     /
                             {                                                                                                                    /
                                       classname* pSingleton = new classname();                           /
                                       if( Register(#classname , pSingleton) )                                     /
                                                  return pSingleton;                                                                 /
                             }                                                                                                                     /
                             else                                                                                                              /
                             {                                                                                                                     /
                                       return pObj;                                                                                       /
                             }                                                                                                                     /
                             return NULL;                                                                                               /
                     }                                                                                                                             /
                                                                                                                                                   /
                     void classname::DestroyInstance()                                                               /
                     {                                                                                                                             /
                             Unregister(#classname);                                                                        /
                     }                                                                                                                             /
                                                                                                                                                   /
                     classname::classname(#param) : CSingleton(#classname)

      // 单件类实例节点
      class CSingletonPtr
      {
              friend class CSingleton;
             private :
                    CSingleton      *m_pSingleton;
                    CSingletonPtr   *m_pNext; 
             public:
                    CSingletonPtr()
                    {
                            m_pSingleton = NULL;
                            m_pNext          = NULL;
                    };
       };

      // 单件基类
     class CSingleton
     {
     protected:
            CSingleton(const char* szSubClassName);
            virtual ~CSingleton();
 
            static bool Register(const char* szSubClassName , CSingleton* pSingleton);
            static void Unregister(const char* szSubClassName);
            static CSingleton* FindInstance(const char* szClassName);
            static int hashMap(const char* szKey);
 
      private:
            static CSingletonPtr* m_Singletons[HASHMAPSIZE];
            char m_szSubClassName[MAX_CLASSNAMELEN];
       };

       CSingletonPtr* CSingleton::m_Singletons[HASHMAPSIZE];

       bool CSingleton::Register(const char* szSubClassName , CSingleton* pSingleton)
       {
               if( szSubClassName[0] == '/0' || pSingleton == NULL )
               {
                      return false;
               }
 
              int              index         = hashMap(szSubClassName);
              CSingletonPtr*   pSingletonPtr = m_Singletons[index];
 
              if( pSingletonPtr == NULL )
              {
                     CSingletonPtr* pTemp = new CSingletonPtr();
                     pTemp->m_pSingleton  = pSingleton;
                     pTemp->m_pNext       = NULL;
                     m_Singletons[index]  = pTemp;
              }
             else
             {
                     CSingletonPtr* pPreSingletonPtr = pSingletonPtr;
       
                    while( 1 )
                    {
                           pSingletonPtr = pSingletonPtr->m_pNext;
                           if( pSingletonPtr == NULL )
                           {
                                  CSingletonPtr *pTemp = new CSingletonPtr();
                                  pTemp->m_pSingleton  = pSingleton;
                                  pTemp->m_pNext       = NULL;
                                  pPreSingletonPtr->m_pNext = pTemp;
                                  break;
                           }
                          pPreSingletonPtr = pSingletonPtr;
                   }
             }
             return true;
      }

      void CSingleton::Unregister(const char* szSubClassName)
      {
              if( szSubClassName[0] == '/0' )
             {
                    return;
             }
 
             int              index         = hashMap(szSubClassName);
            CSingletonPtr*   pSingletonPtr = m_Singletons[index];
 
             if( pSingletonPtr == NULL )
                        m_Singletons[index] = NULL;
             else if( pSingletonPtr->m_pNext == NULL )
             {
                     delete pSingletonPtr;
                     m_Singletons[index] = NULL;
             }
             else if( strcmp(szSubClassName , pSingletonPtr->m_pSingleton->m_szSubClassName) == 0 )
             {
                     m_Singletons[index] = pSingletonPtr->m_pNext;
                     delete pSingletonPtr;
             }
            else
            {
                     CSingletonPtr *pPre;
                     pPre = pSingletonPtr;
       
                     while( pSingletonPtr )
                     {
                           if( strcmp(szSubClassName , pSingletonPtr->m_pSingleton->m_szSubClassName) == 0 )
                           {
                                  pPre->m_pNext = pSingletonPtr->m_pNext;
                                  delete pSingletonPtr;
                                  break;
                           }
                           pPre = pSingletonPtr;
                           pSingletonPtr = pSingletonPtr->m_pNext;
                     }
             }
        }

        CSingleton::CSingleton(const char* szSubClassName)
        {
                 strcpy(m_szSubClassName , szSubClassName);
        }

       CSingleton::~CSingleton()
       {
       }

       CSingleton* CSingleton::FindInstance(const char* szClassName)
       {
                 int index = hashMap(szClassName);
                 CSingletonPtr* pSingletonPtr = m_Singletons[index];
 
                 while( pSingletonPtr )
                 {
                         if( strcmp(szClassName , pSingletonPtr->m_pSingleton->m_szSubClassName) == 0 )
                                    return pSingletonPtr->m_pSingleton;
                         pSingletonPtr = pSingletonPtr->m_pNext;
                 }
   
                return NULL;
        }

        int CSingleton::hashMap(const char* szKey)
        {
               int hashf = 0;
               while( *szKey )
                      hashf += toupper((unsigned char)*szKey++);
              return hashf % HASHMAPSIZE;
        }

使用

        如果我们要生成一个子类,只需如下即可:
       class CChild : public CSingleton
       {
               DECLARE_SINGLETON(CChild , )
         public :
               void Func();
       }

       IMPLEMENT_SINGLETON(CChild , )
       {
       }

       void CChild::Func()
       {

       }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值