• [C++]给C++封装一个多播委托


    一来闲的蛋疼,二来我们代码里面有一些fastdelegate的代码,在clang下面实在编译不过去,所以打算重造一个轮子,至少标准一点(换个编译器能编译过去...)....

    废话不说,上代码:

    // C++版的多播委托,使用boost::function
    // 为了在各个编译器下面都能编译
    // author:egmkang

    #ifndef __ZEVENT_T_H__
    #define __ZEVENT_T_H__
    #include
    <boost/function.hpp>
    #include
    <list>

    template
    <typename T>
    class zEventBaseT
    {
    public:
    typedef T DelegateType;
    typedef std::list
    <DelegateType*> ContainerType;
    typedef typename ContainerType::iterator IterType;

    inline
    void add(DelegateType *p)
    {
    if(p && !contains(p))
    {
    _impl_list.push_back(p);
    }
    }
    inline
    void remove(DelegateType *p)
    {
    _impl_list.remove(p);
    }
    inline
    void operator +=(DelegateType *p)
    {
    add(p);
    }
    inline
    void operator -=(DelegateType *p)
    {
    remove(p);
    }
    protected:
    zEventBaseT(){}
    virtual ~zEventBaseT()
    {
    _impl_list.clear();
    }
    inline
    bool contains(DelegateType *p)
    {
    for(IterType iter = _impl_list.begin();
    iter
    != _impl_list.end();
    ++iter)
    {
    if(*iter == p) return true;
    }
    return false;
    }
    protected:
    ContainerType _impl_list;
    };

    template
    <typename T>
    class zEventT;

    #define EVENT_CALL(...) \
    { \
    ContainerType
    & impl = this->_impl_list; \
    for(IterType iter = impl.begin(); \
    iter
    != impl.end(); \
    ++iter) \
    { \
    (
    *(*iter))(__VA_ARGS__); \
    } \
    }

    //FUNCTION_ARGS = 0
    template<>
    class zEventT<boost::function<void()> >:
    public zEventBaseT<boost::function<void()> >
    {
    public:
    void operator()()
    {
    EVENT_CALL();
    }
    };

    //FUNCTION_ARGS = 1
    template<typename P1>
    class zEventT<boost::function<void(P1)> >:
    public zEventBaseT<boost::function<void(P1)> >
    {
    public:
    typedef typename zEventBaseT
    <boost::function<void(P1)> >::ContainerType ContainerType;
    typedef typename zEventBaseT
    <boost::function<void(P1)> >::IterType IterType;
    void operator()(P1 p1)
    {
    EVENT_CALL(p1);
    }
    };

    //FUNCTION_ARGS = 2
    template<typename P1,typename P2>
    class zEventT<boost::function<void(P1,P2)> >:
    public zEventBaseT<boost::function<void(P1,P2)> >
    {
    public:
    typedef typename zEventBaseT
    <boost::function<void(P1,P2)> >::ContainerType ContainerType;
    typedef typename zEventBaseT
    <boost::function<void(P1,P2)> >::IterType IterType;
    void operator()(P1 p1,P2 p2)
    {
    EVENT_CALL(p1,p2);
    }
    };

    //FUNCTION_ARGS = 3
    template<typename P1,typename P2,typename P3>
    class zEventT<boost::function<void(P1,P2,P3)> >:
    public zEventBaseT<boost::function<void(P1,P2,P3)> >
    {
    public:
    typedef typename zEventBaseT
    <boost::function<void(P1,P2,P3)> >::ContainerType ContainerType;
    typedef typename zEventBaseT
    <boost::function<void(P1,P2,P3)> >::IterType IterType;
    void operator()(P1 p1,P2 p2,P3 p3)
    {
    EVENT_CALL(p1,p2,p3);
    }
    };

    //FUNCTION_ARGS = 4
    template<typename P1,typename P2,typename P3,typename P4>
    class zEventT<boost::function<void(P1,P2,P3,P4)> >:
    public zEventBaseT<boost::function<void(P1,P2,P3,P4)> >
    {
    public:
    typedef typename zEventBaseT
    <boost::function<void(P1,P2,P3,P4)> >::ContainerType ContainerType;
    typedef typename zEventBaseT
    <boost::function<void(P1,P2,P3,P4)> >::IterType IterType;
    void operator()(P1 p1,P2 p2,P3 p3,P4 p4)
    {
    EVENT_CALL(p1,p2,p3,p4);
    }
    };

    #endif//__ZEVENT_T_H__

    这里最多支持函数有四个参数,如果想要支持多的话,自己添上去就行.

    使用该类的代码:

    #include "zEvent.hpp"
    #include
    <boost/bind.hpp>
    #include
    <iostream>
    #include
    <stdlib.h>

    void printA(int a,int b)
    {
    std::cout
    << (a+b) << std::endl;
    }
    void printB(int a,int b)
    {
    std::cout
    << (a + b) << std::endl;
    }
    int main()
    {
    typedef zEventT
    <boost::function<void(int)> > PrintEvent;
    typedef PrintEvent::DelegateType DelegateType;

    PrintEvent _event;
    DelegateType delegate1
    = boost::bind(&printA,10,_1);
    DelegateType delegate2
    = boost::bind(&printB,12,_1);

    _event
    += &delegate1;
    _event
    += &delegate2;
    _event(
    18);

    std::cout
    << std::endl;
    _event
    -= &delegate1;
    _event(
    19);

    system(
    "pause");
    return 0;
    }

    之所以委托链内存的是指针,原因有2:

    1. 指针很容易比较

    2. boost::function比较貌似有一点问题

    用boost::function有一点好处,就是可以通过boost::bind完成一些复杂的功能:-),而且boost::function也是C++0x的内容之一

    PS:

    随手写了一个,至少兼容VC,GCC 4.4+,clang 2.8,有什么问题或者建议都可以留言,欢迎斧正.

    clang真是一个好东西啊,准备把我们服务器的代码改的在clang下面可以编译过去,用clang做代码分析检查:-D

    我自己对容器内存的顺序没要求,所以把容器换成set了哈,哈哈

  • 相关阅读:
    [css]display: table-cell,用div做分列布局
    [css]《CSS知多少》
    关于安装Android Studio的一些问题的解决方法
    枚举
    揭开计算机的神秘面纱
    Android模拟器访问本地Web应用
    Android开发中常用的Eclipse快捷键
    详解Windows平台搭建Androiod开发环境
    Web 应用的安全性
    坚持才能成功------王健林
  • 原文地址:https://www.cnblogs.com/egmkang/p/CPP_Delegate_And_Event.html
Copyright © 2020-2023  润新知