C++ delegate

来源:互联网 发布:vb 表格控件 编辑:程序博客网 时间:2024/04/30 15:47
#ifndef __delegate_h__#define __delegate_h__#include <vector>class IDelegateObject{public:virtual bool istype(const std::type_info& typeinfo) = 0;virtual bool equal(IDelegateObject*) = 0;virtual void invoke() = 0;};static void DestroyDelegateObject( IDelegateObject*& ppObj ){if( ppObj ){delete ppObj;ppObj = NULL;}}class TDelegate;class TDelegateFunction : public IDelegateObject{friend class TDelegate;public:typedef void (*DelegateImpl)();public:TDelegateFunction( DelegateImpl pImpl ){m_pImpl = pImpl;}static TDelegateFunction* TDelegateFunction::New( DelegateImpl pImpl ){TDelegateFunction* pDelegate = new TDelegateFunction( pImpl );return pDelegate;}static void TDelegateFunction::Destory( TDelegateFunction*& pDelegate ){if( pDelegate ){delete pDelegate;pDelegate = NULL;}}protected: bool istype( const std::type_info& typeinfo ) { return ( typeid(TDelegateFunction) == typeinfo ) ? true : false; } bool equal( IDelegateObject* pobj ) {if( pobj != 0 && pobj->istype( typeid( TDelegateFunction ) ) ) { TDelegateFunction* cast_ptr = static_cast<TDelegateFunction*>( pobj ); return ( cast_ptr->m_pImpl == m_pImpl ); } return false; } virtual void invoke() { if( m_pImpl == 0 ) return; (m_pImpl)(); }private:DelegateImpl m_pImpl;};template<typename T>class TDelegateMethod : public IDelegateObject{friend class TDelegate;public:typedef void (T::*DelegateImpl)();public:TDelegateMethod( T* pObj, DelegateImpl pImpl ){m_pObj = pObj;m_pImpl = pImpl;}static TDelegateMethod* TDelegateMethod::New( T* pObj, DelegateImpl pImpl ){TDelegateMethod* pDelegate = new TDelegateMethod( pObj, pImpl );return pDelegate;}static void TDelegateMethod::Destory( TDelegateMethod*& pDelegate ){if( pDelegate ){delete pDelegate;pDelegate = NULL;}}protected:bool istype( const std::type_info& typeinfo ){return ( typeid( TDelegateMethod ) == typeinfo ) ? true : false;}bool equal( IDelegateObject* pobj ){if( pobj != 0 && pobj->istype( typeid( TDelegateMethod ) ) ){TDelegateMethod* cast_ptr = static_cast<TDelegateMethod*>( pobj );return ( cast_ptr->m_pObj == m_pObj && cast_ptr->m_pImpl == m_pImpl );}return false;}virtual void invoke() { if( m_pImpl == 0 || m_pObj == 0) return; (m_pObj->*m_pImpl)(); }private:T* m_pObj;DelegateImpl m_pImpl;};class TDelegate{private:std::vector<IDelegateObject*> m_objs;typedef std::vector<IDelegateObject*>::iterator OBJITER;TDelegate(const TDelegate& src);void operator=(const TDelegate& src);public:TDelegate(){}~TDelegate(){OBJITER iter = m_objs.begin();while( iter != m_objs.end() ){if( (*iter) != 0 ){DestroyDelegateObject( (*iter) );}iter = m_objs.erase(iter);}}public:void operator()(){OBJITER iter = m_objs.begin();while( iter != m_objs.end() ){(*iter)->invoke();iter++;}}TDelegate& operator +=( IDelegateObject* pObj ) {OBJITER iter = m_objs.begin();for( ; iter != m_objs.end(); iter++){if( (*iter) != 0 && (*iter)->equal(pObj) ){DestroyDelegateObject(pObj);return *this;}}m_objs.push_back( pObj );return *this; }TDelegate& operator -=( IDelegateObject* pObj ) {OBJITER iter = m_objs.begin();for( ; iter != m_objs.end(); iter++){if( (*iter) != 0 && (*iter)->equal(pObj) ){if( (*iter) != pObj )DestroyDelegateObject((*iter));m_objs.erase( iter );break;}}DestroyDelegateObject( pObj );return *this; }};#endif