2015-03-04 3 views
0

Попытка ретро-совместимости не-COM-класса с защитой на основе ссылок, которая предотвращает ее деконструкцию, когда в настоящее время выполняется какой-либо из ее методов-членов.Обобщение класса подсчета ссылок для использования с неспецифическими защищенными классами

Написал небольшой класс, предназначенный для вызова AddRef при строительстве, и Release on deonstruction; объявить экземпляр при входе в функции классов защищенных классов - работает нормально, но он связан с защищенным классом, что означает, что я могу использовать его только с этим классом.

Я хотел бы обобщить его так, чтобы его можно было использовать с любым классом. Я думал, может быть, шаблоны помогут, но я не знаю достаточно о них, чтобы писать классы, которые их используют. Вот класс, как она существует в настоящее время, работает, но ограничивается используется в случаях ClsEditWndData

#ifndef _ClsProtectMe_h_ 
# define _ClsProtectMe_h_ 
    typedef void (ClsEditWndData::*pfnREFCOUNTER)(); 
    class ClsProtectMe 
    { 
     public: 
      ClsProtectMe(        // constructor 
       pfnREFCOUNTER pfnAddRef,    // pointer to callers' AddRef 
       pfnREFCOUNTER pfnRelease,    // pointer to callers' Release 
       ClsEditWndData* pThis) :    // pointer to caller 
        m_pfnAddRef(pfnAddRef),   // init stored AddRef address 
        m_pfnRelease(pfnRelease),   // init stored Release address 
        m_pThis(pThis)     // init stored instance address 
      {           // =========================== 
       if(m_pThis != NULL)     // must have non-null instance 
        if(m_pfnRelease != NULL)   // must have non-null release 
         if(m_pfnAddRef != NULL)  // must have non-null addref 
          (m_pThis->*m_pfnAddRef)(); // call the addref function 
      }           // =========================== 

      virtual ~ClsProtectMe(void)     // destructor 
      {           // =========================== 
       if(m_pThis != NULL)     // must have non-null instance 
        if(m_pfnRelease != NULL)   // must have non-null release 
         if(m_pfnAddRef != NULL)  // must have non-null addref 
          (m_pThis->*m_pfnRelease)(); // call the release function 
      }           // =========================== 
     private: 
      pfnREFCOUNTER m_pfnAddRef;    // stored pointer to AddRef function 
      pfnREFCOUNTER m_pfnRelease;    // stored pointer to Release function 
      ClsEditWndData* m_pThis;     // stored pointer to instance 
    }; 
#endif 

ответ

0

Решение было намного проще, чем я ожидал. Небольшое исследование классов шаблонов дало мне ответ, который я искал. Я был в состоянии 'templateize' указанного класса следующим образом:

template <class T> class ClsProtect  
{ 
    public: 
     ClsProtect(void (T::*add)(), void (T::*release)(), T* pThis) 
      : m_pfnAdd(add), m_pfnRelease(release), m_pThis(pThis) 
     { 
      if(m_pThis != NULL) 
       if(m_pfnAdd != NULL) 
        if(m_pfnRelease != NULL) 
         (m_pThis->*m_pfnAdd)(); 
     }; 
     virtual ~ClsProtect(){ 
      if(m_pThis != NULL) 
       if(m_pfnAdd != NULL) 
        if(m_pfnRelease != NULL) 
         (m_pThis->*m_pfnRelease)(); 
     }; 
    private: 
     void (T::* m_pfnAdd)(); 
     void (T::* m_pfnRelease)(); 
     T*   m_pThis; 
}; 

использование:

void ClsEditWndData::OnKeyDown(WPARAM wParam, LPARAM) 
{ 
    ClsProtect<ClsEditWndData> objProtect( 
     &ClsEditWndData::AddRef, 
     &ClsEditWndData::Release, 
     this); 
    ...<whatever, don't care...>... 
} 
Смежные вопросы