当前位置:编程学习 > C/C++ >>

C++实现的委托机制(2)

1.实现任意参数的函数委托

按上一篇文章的方法,你已经可以使用无参数的函数委托了。当然,这远远不够。要实现任意参数的函数委托,这里的任意参数包括任意个数和任意类型。任意类型这个容易解决,使用模板就行,但任意参数个数呢?

注:最终的实现代码可以在这里下载:/2011/1009/20111009023128248.rar
 

单参函数委托  
template<typename TP1> 
class CMultiDelegate1{}; 
// 双参函数委托  
template<typename TP1, typename TP2> 
class CMultiDelegate2{}; 
// 单参函数委托
template<typename TP1>
class CMultiDelegate1{};
// 双参函数委托
template<typename TP1, typename TP2>
class CMultiDelegate2{};

注意类名是不一样的,分别为CMultiDelegate1和CMultiDelegate2

C++里面,类名相同但模板参数个数不同是会当成一个类对待的,所以那样编译不过的

这样是不是很麻烦呢?

不是很麻烦,是相当麻烦。因为不单单是CMultiDelegate要实现多个参数的版本

连IDelegate、CStaticDelegate和CMethodDelegate都要实现对应的多个参数的版本!

其实所有版本的内部实现几乎一样,下面给出双参函数的版本

template<typename TP1, typename TP2> 
class IDelegate2 

public: 
    virtual ~IDelegate2() { } 
    virtual bool isType( const std::type_info& _type) = 0; 
    virtual void invoke( TP1 p1, TP2 p2 ) = 0; 
    virtual bool compare( IDelegate2<typename TP1, typename TP2> *_delegate) const = 0; 
}; 
template<typename TP1, typename TP2> 
class CStaticDelegate2 : public  IDelegate2<typename TP1, typename TP2> 

public: 
    typedef void (*Func)( TP1 p1, TP2 p2 ); 
    CStaticDelegate2 (Func _func) : mFunc(_func) { } 
    virtual bool isType( const std::type_info& _type) { return typeid( CStaticDelegate2<typename TP1, typename TP2> ) == _type; } 
    virtual void invoke( TP1 p1, TP2 p2 ) 
    { 
        mFunc( p1, p2 ); 
    } 
    virtual bool compare( IDelegate2<typename TP1, typename TP2> *_delegate) const 
    { 
        if (0 == _delegate || !_delegate->isType(typeid(CStaticDelegate2 <typename TP1, typename TP2>)) ) return false; 
        CStaticDelegate2 <typename TP1, typename TP2> * cast = static_cast<CStaticDelegate2 <typename TP1, typename TP2> *>(_delegate); 
        return cast->mFunc == mFunc; 
    } 
    virtual bool compare(IDelegateUnlink * _unlink) const { return false; } 
private: 
    Func mFunc; 
}; 
template <typename T, typename TP1, typename TP2> 
class CMethodDelegate2 : public  IDelegate2 <typename TP1, typename TP2> 

public: 
    typedef void (T::*Method)( TP1 p1, TP2 p2 ); 
    CMethodDelegate2(T * _object, Method _method) : mObject(_object), mMethod(_method) { } 
    virtual bool isType( const std::type_info& _type) { return typeid( CMethodDelegate2 <T, TP1, TP2> ) == _type; } 
    virtual void invoke( TP1 p1, TP2 p2 ) 
    { 
        (mObject->*mMethod)( p1, p2 ); 
    } 
    virtual bool compare(  IDelegate2 <typename TP1, typename TP2>  * _delegate) const 
    { 
        if (0 == _delegate || !_delegate->isType(typeid(CMethodDelegate2 <T, TP1, TP2>)) ) return false; 
        CMethodDelegate2 <T, TP1, TP2>  * cast = static_cast<  CMethodDelegate2 <T, TP1, TP2>  * >(_delegate); 
        return cast->mObject == mObject && cast->mMethod == mMethod; 
    } 
private: 
    T * mObject; 
    Method mMethod; 
}; 
template   <typename TP1, typename TP2> 
inline  delegates::IDelegate2 <typename TP1, typename TP2>  * newDelegate( void (*_func)( TP1 p1, TP2 p2 ) ) 

    return new delegates::CStaticDelegate2 <typename TP1, typename TP2>  (_func); 

template <typename T, typename TP1, typename TP2> 
inline  delegates::IDelegate2 <typename TP1, typename TP2>  * newDelegate( T * _object, void (T::*_method)( TP1 p1, TP2 p2 ) ) 

    return new delegates::CMethodDelegate2  <T, TP1, TP2>  (_object, _method); 

template   <typename TP1, typename TP2> 
class CMultiDelegate2 

public: 
    typedef IDelegate2 <typename TP1, typename TP2>  IDelegate; 
    typedef typename std::list<IDelegate*> ListDelegate; 
    typedef typename ListDelegate::iterator ListDelegateIterator; 
    typedef typename ListDelegate::const_iterator ConstListDelegateIterator; 
    CMultiDelegate2 () { } 
    ~CMultiDelegate2 () { 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; 
            } 
        } 
    } 
    CMultiDelegate2  <typename TP1, typename TP2> & operator+=(IDelegate* _delegate) 
    { 
        for (ListDelegateIterator iter=mListDelegates.begin(); iter!=mListDelegates.end(); ++iter) 
     &n

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,