C++实现委托机制之完整代码实现(一)

头文件 MyDelegate.h 代码如下:

#include <typeinfo>
#include <list>
#include <vector>

class IDelegate  
{  
public:  
    virtual ~IDelegate() { }  
    virtual bool isType(const type_info& _type) = 0;  
    virtual void invoke() = 0;  
    virtual bool compare(IDelegate *_delegate) const = 0;  
};  
 

class CStaticDelegate : public IDelegate  
{  
public:  
    typedef void (*Func)();  
  
    CStaticDelegate(Func _func) : mFunc(_func) { }  
  
    virtual bool isType(const type_info& _type) { return typeid(CStaticDelegate) == _type; }  
  
    virtual void invoke() { mFunc(); }  
  
    virtual bool compare(IDelegate *_delegate) const  
    {  
        if (0 == _delegate || !_delegate->isType(typeid(CStaticDelegate)) ) return false;  
        CStaticDelegate * cast = static_cast<CStaticDelegate*>(_delegate);  
        return cast->mFunc == mFunc;  
    }  
  
private:  
    Func mFunc;  
}; 

inline IDelegate* newDelegate( void (*_func)() )  
{  
    return new CStaticDelegate(_func);  
}  
  
template<class T>  
inline IDelegate* newDelegate( T * _object, void (T::*_method)() )  
{  
    return new CMethodDelegate<T>(_object, _method);  
} 

template<class T>  
class CMethodDelegate : public IDelegate  
{  
public:  
    typedef void (T::*Method)();  
  
    CMethodDelegate(T * _object, Method _method) : mObject(_object), mMethod(_method) { }  
  
    virtual bool isType( const std::type_info& _type) { return typeid(CMethodDelegate<T>) == _type; }  
  
    virtual void invoke()  
    {  
        (mObject->*mMethod)();  
    }  
  
    virtual bool compare(IDelegate *_delegate) const  
    {  
        if (0 == _delegate || !_delegate->isType(typeid(CMethodDelegate<T>))) return false;  
        CMethodDelegate<T>* cast = static_cast<CMethodDelegate<T>*>(_delegate);  
        return cast->mObject == mObject && cast->mMethod == mMethod;  
    }  
  
private:  
    T * mObject;  
    Method mMethod;  
};  


class CMultiDelegate  
{  
public:  
    typedef std::list<IDelegate*> ListDelegate;  
    typedef ListDelegate::iterator ListDelegateIterator;  
    typedef ListDelegate::const_iterator ConstListDelegateIterator;  
  
    CMultiDelegate () { }  
    ~CMultiDelegate () { clear(); }  
  
    bool empty() const  
    {  
        for (ConstListDelegateIterator iter = mListDelegates.begin(); iter!=mListDelegates.end(); ++iter)  
        {  
            if (*iter) return false;  
        }  
        return true;  
    }  
  
    void clear()  
    {  
        for (ListDelegateIterator iter=mListDelegates.begin(); iter!=mListDelegates.end(); ++iter)  
        {  
            if (*iter)  
            {  
                delete (*iter);  
                (*iter) = 0;  
            }  
        }  
    }  
  
    CMultiDelegate& operator+=(IDelegate* _delegate)  
    {  
        for (ListDelegateIterator iter=mListDelegates.begin(); iter!=mListDelegates.end(); ++iter)  
        {  
            if ((*iter) && (*iter)->compare(_delegate))  
            {  
                delete _delegate;  
                return *this;  
            }  
        }  
        mListDelegates.push_back(_delegate);  
        return *this;  
    }  
  
    CMultiDelegate& operator-=(IDelegate* _delegate)  
    {  
        for (ListDelegateIterator iter=mListDelegates.begin(); iter!=mListDelegates.end(); ++iter)  
        {  
            if ((*iter) && (*iter)->compare(_delegate))  
            {  
                if ((*iter) != _delegate) delete (*iter);  
                (*iter) = 0;  
                break;  
            }  
        }  
        delete _delegate;  
        return *this;  
    }  
  
    void operator()( )  
    {  
        ListDelegateIterator iter = mListDelegates.begin();  
        while (iter != mListDelegates.end())  
        {  
            if (0 == (*iter))  
            {  
                iter = mListDelegates.erase(iter);  
            }  
            else  
            {  
                (*iter)->invoke();  
                ++iter;  
            }  
        }  
    }  
  
private:  
    CMultiDelegate (const CMultiDelegate& _event);  
    CMultiDelegate& operator=(const CMultiDelegate& _event);  
  
private:  
    ListDelegate mListDelegates;  
};  

源文件 main.cpp 代码如下:

#include <iostream>
#include "MyDelegate.h"

using namespace std;

void Say()  
{  
    printf("你好\n");  
}  
class A  
{  
public :  
    void Say(){ printf("你不好\n"); }  
};  

int main()
{
	CMultiDelegate onclick;  
    onclick += newDelegate(Say);  
  
    onclick += newDelegate(&A(),&A::Say);   //注意这里不能传入 new A(), 因为会内存泄漏。  
  
    onclick();  

	return 0;
}


运行结果如下:

你好
你不好


代码详解见:C++实现委托机制(一)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值