zoukankan      html  css  js  c++  java
  • C++Event机制的简单实现

          C++ Event Model

    事件模型

      对发生的事件作出的响应——事件模型。

    1 事件:

      在面向对象中,就是对象的属性或者状态发生了变化,操作或者接收到了某些动作时,

    向外发出了这种变化或者动作对应的通知。   

        

    2 事件模型包括的元素:

        

        

    3 事件模型过程:


        

    二 代码实现


    1 EventManager

    /*----------------------------------------------------------------*/
    /* class Object 响应事件函数的类必须是从Object派生下来 */
    /*----------------------------------------------------------------*/
    class Object
    {
    };

    /*----------------------------------------------------------------*/
    /* class Event 模板参数为 返回类型 和响应函数参数类型 */
    /* 仅实现一个参数的事件响应函数 */
    /*----------------------------------------------------------------*/

    template<typename rtnTtpe,typename ArgType>
    class Event
    {
    //使每个事件最多关联响应的函数个数
    #define EVENT_LIST_MAX_NUM (10)

    typedef rtnTtpe (Object::*pMemFunc)(ArgType arg);

    public:
    Event()
    {
    m_totalFunc = 0;
    m_obj = NULL;
    for (int i = 0; i < EVENT_LIST_MAX_NUM; i++)
    {
    m_func[i] = NULL;
    }
    }

    //关联回调成员函数
    template <class _func_type>

    void associate(Object *obj, _func_type func)
    {
    m_obj = obj;
    m_func[m_totalFunc] = static_cast<pMemFunc> (func);
    m_totalFunc++;
    }
    //删除事件关联回调成员函数
    template <class _func_type>

    void disAssociate(Object *obj, _func_type func)
    {
    if (obj != m_obj)
    {
    return;
    }

    //查找
    for (int i = 0; i < m_totalFunc; i++)

    {
    if (m_func[i] == func)
    {
    break;
    }
    }

    //移动删除
    for (i ; i < m_totalFunc - 1; i++)

    {
    m_func[i] = m_func[i + 1];
    }

    m_func[i] = NULL;
    m_totalFunc --;
    }

    //执行关联的回调函数
    void sendEvent(ArgType arg)

    {
    for (int i = 0; i < m_totalFunc; i++)
    {
    if (m_func[i] != NULL)
    {
    ((m_obj->*pMemFunc(m_func[i])))(arg);
    }
    }
    }
    private:
    Object* m_obj;
    pMemFunc m_func[EVENT_LIST_MAX_NUM];
    int m_totalFunc;
    };


    2 测试代码

    /*----------------------------------------------------------------*/
    /* class TestEvent */
    /*----------------------------------------------------------------*/
    class TestEvent
    {
    public:
    void test()
    {
    //do somsthing
    //……

    //触发事件
    myEvent.sendEvent(100);

    myEvent.sendEvent(200);
    }
    public:
    //定义事件
    Event<bool,int> myEvent;

    };
    /*----------------------------------------------------------------*/
    /* class TestClass */
    /*----------------------------------------------------------------*/
    class TestClass:public Object
    {
    public:
    TestClass()
    {
    //关联事件
    m_event.myEvent.associate(this,&TestClass::executeCb1);

    m_event.myEvent.associate(this,&TestClass::executeCb2);
    }

    //事件响应函数
    bool executeCb1(int result)

    {
    cout<<"executeCb1 result = "<<result<<endl;
    return true;
    }
    //事件响应函数
    bool executeCb2(int result)

    {
    cout<<"executeCb2 result = "<<result<<endl;
    return true;
    }

    void execute()
    {
    m_event.test();
    }
    void stop()
    {
    //删除事件关联函数
    m_event.myEvent.disAssociate(this,&TestClass::executeCb1);

    }
    private:
    TestEvent m_event;
    };
    int main()
    {
    TestClass testObj;

    testObj.execute();
    testObj.stop();
    testObj.execute();

    return 0;
    }


    3 输出结果

    <---------------first begin---------------
    executeCb1 result = 100
    executeCb2 result = 100
    executeCb1 result = 200
    executeCb2 result = 200
    ---------------after delete---------------
    executeCb2 result = 100
    executeCb2 result = 200

  • 相关阅读:
    【已解决】allure空白页 报错 Uncaught TypeError: P.a.registerLanguage is not a function,Uncaught ReferenceError: allure is not defined问题解决方法
    【转】SQLServer查询死锁
    opencv-Mask(掩膜)
    opencv-cvtColor图像制式转换
    opencv-saturate_cast防溢出函数
    opencv-convertTo转换数据格式
    opencv-imwrite保存函数
    opencv-imshow显示函数
    opencv-setTo设置值
    我的蓝牙设备
  • 原文地址:https://www.cnblogs.com/bastard/p/2318417.html
Copyright © 2011-2022 走看看