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

时间:2010-08-31 11:51:15

标签: c++ events signals-slots

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

如果我理解正确,“事件系统”使用观察者模式:一些对象正在观察,等待某事发生......以及其他一些发送信号。好的。

所以,让我说我有观察员课,有这样的事情:

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

我的问题是:如何动态管理应该做什么样的事情?我见过很多人特意说不使用函数指针。对于我目前的需要,我可以做一个switch语句,一个枚举类型,并选择不同的行为,但这不是很令人满意。那么,如果它不是函数指针,它是如何完成的?

2 个答案:

答案 0 :(得分:4)

有许多不同的实现可能(无论语言如何),但抽象的想法是:

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

    这是一个简单的实现:

    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
            }
    
         }
    };
    

    这是一个基本的例子,但这可能有助于你理解这个想法。

答案 1 :(得分:1)

请参阅Pete Goodliffe的excellent article,根据所通知的事件类型,路由到不同的方法。

如果您需要在单个事件类型中选择操作,那么通常您的代码会根据通知中传递的数据进行选择。