代码之家  ›  专栏  ›  技术社区  ›  Raveline

C++中事件系统的原理是什么?

  •  3
  • Raveline  · 技术社区  · 14 年前

    首先,我知道有很多优秀的实现(Qt、Boost、cpp event等等),但是我问这个问题是因为我想知道它是如何工作的!

    如果我理解正确的话,“事件系统”使用的是观察者模式:一些对象正在观察,等待某事发生。。。还有一些发出信号。好吧。

    所以,假设我有一个观察者类,有这样的东西:

    void Observer::getNotified() 
    {
        // Do stuff
    }
    

    我的问题是:如何动态管理应该做什么样的事情?我见过很多人明确表示不要使用函数指针。对于我当前的需要,我可以执行switch语句、枚举类型,并选择不同的行为,但这不是很令人满意。那么,如果不是函数指针,那么它是如何实现的呢?

    2 回复  |  直到 14 年前
        1
  •  4
  •   Klaim    14 年前

    有很多不同的实现方式(不管是哪种语言),但抽象的想法是:

    1. 有一个事件类型标识符来知道观察到的对象触发了哪些事件(可以是任何有效的事件);
    2. 有一个观察者列表(或者几个,按事件类型一个?)在注册对象中注册-假设观察者是函子(函数指针或类似于函数的对象)或具有已知接口的对象(使用调用离子事件的虚拟方法);
    3. 当一个事件被触发时(通过调用观察对象上的函数),我们只需浏览为事件类型注册的观察者列表,并将事件信息(id加上可能的数据)传递给要处理的观察者;

    enum EventType
    {
       Event_A,
       Event_B,
    };
    
    class Observer // for this example i'll suppose observer inherits this class
    {
        virtual void catchEvent( EventType e ) = 0; // for sake of the example I just need the event type, not the data, but it's often required
    
        virtual ~Observer(){}; // virtual base classes require this to work fine.
    };
    
    class Observed
    {
          typedef std::vector<Observer*> ObserverList; 
          typedef std::map< EventType, ObserverList > ObserversTable;
          ObserversTable m_observers; // we have observers for each event type
    
    public:
    
         void addObserver( Observer& observer, EventType eType ) 
         { m_observers[ eType ].push_back( observer ); } // this is simplist, to say the least...
    
         void sendEvent( EventType event ) // here we send the event, it will be catched by observers
         { // note : often this type of system is "buffered", but here we will process it immediatly as it's a simple example
    
            ObserverList& observers = m_observers[ event ];  
            for ( ObserverList::iterator it = observers.begin(); it != observers.end(); ++it )
            {
                  Observer* observer = *it;
                  observer->catchEvent( event ); // here an observer receive the event
            }
    
         }
    };
    

        2
  •  1
  •   Seb Rose    14 年前

    你看这个 excellent article 来自Pete Goodliffe,它根据所通知的事件类型路由到不同的方法。