我正在尝试实现订阅者-发布者模式。我的基类Subscriber
没有侦听器方法,而是声明了类型Handler
。这背后的想法是,派生类将能够有多个处理程序,这些处理程序将实现此类型并可以传递给Publisher
。我正在尝试调用Notify
方法中的处理程序,但是我得到了一个错误,状态是expression must have pointer-to-member type
。我怎么才能把我的函数指针转换为一个成员类型,用我的方法可能吗?
class Subscriber {
public:
typedef void (*Handler)();
};
struct Subscription {
Subscriber *instance;
Subscriber::Handler handler;
};
class Publisher {
protected:
std::vector<Subscription> subscriptions;
public:
virtual void AddSubscriber(Subscription subscription) {
this->subscriptions.push_back(subscription);
};
virtual void Notify() {
for (auto subscription : this->subscriptions) {
auto i = subscription.instance;
auto h = subscription.handler;
(i->*h)();
}
};
};
我的目标是做一个可扩展的系统能够做这样的事情
struct KeyboardSubscription : Subscription {
Event event_type;
Key listened_key;
}
class GUI : Subscriber {
void OpenMenu() { ... }; // implementing Subscriber::Handler
void CloseMenu() { ... }; // implementing Subscriber::Handler too
}
class Keyboard : Publisher {
void Notify() {
for (KeyboardSubscription subscription : this->subscriptions) {
auto i = subscription.instance;
auto h = subscription.handler;
if (subscription.event_type == this->event_type &&
subscription.listened_key == this->pressed_key)
(i->*h)();
}
}
}
int main() {
// init GUI and Keyboard...
KeyboardSubscription sub1;
sub1.instance = gui_instance;
sub1.handler = &GUI::OpenMenu;
sub1.event_type = Key_Down;
sub1.listened_key = Enter;
KeyboardSubscription sub2;
sub2.instance = gui_instance;
sub2.handler = &GUI::CloseMenu;
sub2.event_type = Key_Down;
sub2.listened_key = Esc;
keyboard_instance.AddSubscription((Subscription)sub1);
keyboard_instance.AddSubscription((Subscription)sub2);
}
2条答案
按热度按时间eqqqjvef1#
1.也许你不需要Subscription.like这个
2.you 只需要在Notify()中调用handle()就可以了。
kh212irz2#
我已经实现了我想要的。我只需要像这样声明一个函数类型:
下面是一个完整的例子,它可以在没有任何警告的情况下编译,并按预期工作
输出如下: