【发布时间】:2011-10-03 18:49:03
【问题描述】:
我正在使用此处找到的 Signal-Slot C++ 实现:https://github.com/pbhogan/Signals 在我正在开发的用户界面库中实现事件侦听器。
面向用户的 API 如下所示:
class DialEventListener : public EventListener {
void handleEvent(Event event){
…
cout << "Event on" << event.source.name << end;
}
}
int main(){
Interactor dial1;
dial1.addListener(ROTATE_EVENT, DialEventListener());
…
}
要定义事件侦听器,用户将继承EventListener 以创建自定义事件处理程序。但是在我使用 Signals.h 代码的Interactor::addListener() 的实现中,您必须提供一个成员函数指针以及一个类实例指针来将一个 Delegate 连接到某个 Signal。
下面是一段代码 sn-p,展示了我如何尝试使用 Signals 来实现事件侦听器。我使用从EventTypes 到Signal 的映射来说明触发多种类型事件的交互器。
typedef map< EventType, Signal1<Event> > EventTypeListenerMap;
class Interactor {
private:
EventTypeListenerMap listener_map;
public:
void TriggerEvent(Event e){
Signal1<Event> signal = listener_map[e.type];
signal(e);
}
void addListener(EventType e_type, EventListener listener){
…
//Find the signal for a particular kind of event.
Signal1<TUIKitEvent> signal = listener_map[e_type];
//Plug a delegate into that signal's slot
signal.Connect( &listener, &EventListener::handleEvent);
}
void addListener(EventType e_type, EventListener listener, void (EventListener::*handler)(Event)){
…
Signal1<TUIKitEvent> signal = listener_map[e_type];
signal.Connect( &listener, handler);
}
}
class EventListener {
virtual void handleEvent(Event event){
}
}
我使用 Signal-Slot 实现的事实应该对用户隐藏,所以我只是编写了这个版本的 Interactor::addListener(EventType, EventListener, void (EventListener::*)) 作为健全性检查,以确保我传递了正确的成员函数指针以进行绑定到那个信号。但是成员函数指针是特定于类的,那么如何定义一个具有签名的函数,该函数接受指向从 EventListener 派生的类的方法的指针,而这些方法可能还不存在?
【问题讨论】:
-
我认为问题不是很清楚...为什么要将成员函数指针传递给派生方法,而不仅仅是将成员函数传递给基类型并具有动态dispatch 为你解决最终的覆盖?也许您应该添加一小段代码,指出用户代码的外观以及您希望从中获得的行为...
标签: c++ templates function-pointers observer-pattern