gpt4 book ai didi

c++ - 在 C++ 中创建可装饰的有效事件处理类型

转载 作者:行者123 更新时间:2023-11-30 03:06:19 24 4
gpt4 key购买 nike

在过去的几天里,这真的让我很痛苦。我实际上有一些类似于 Szymon Gatner 在他的精彩文章中解释的东西,发现 here . (查看演示代码中的 EventHandler 类)

这是我在网络上找到的少数几篇解释得很好的文章之一如何创建具有可扩展界面的类型。我特别喜欢由此产生的使用语法,非常易于理解。

不过,我还有一件事想用这个类型做,那就是允许它被装饰。现在,用额外的数据成员装饰它是一回事,但我希望装饰也能扩展接口(interface),函数 EventHandler::handleEvent 是唯一需要公开的方法。

现在,不幸的是,EventHandler::registerEventFunc 方法是模板化的。这意味着我无法在 EventHandler 继承的更多基类(例如 HandlerBase)中将其定义为虚方法。

我的问题是是否有人对如何解决问题(使 EventHandler 可装饰)有任何好的想法。

我试过创建方法

1)

void registerEventFunc(boost::function<void()> * _memFn);

和2)

void registerEventFunc(boost::function<void(*SomeDerivedEvent*)> * _memFn);

和3)

void registerEventFunc(boost::function<void(EventBase*)> * __memFn);

对于 1,如果我这样做,我将丢失回调的类 Event 派生参数类型的 typeid。对于 2,我必须为这个类计划注册的尽可能多的事件回调重载函数对于 3,多态性在模板参数中不起作用(如果我错了请纠正我)。

我最接近允许将函数虚拟化的是 1,,但我必须在创建 boost::function 对象时将参数绑定(bind)到 boost::function,并且以后不能在 EventHandler::handleEvent 的主体中对其使用 lambda。

class FooEvent : public Event
{
public:
FooEvent(int _val) : Event(), val(_val){}
int val;
};


class MyHandler : public EventHandler
{
public:
MyHandler()
{
registerEventFunc(new boost::function<void()>(boost::bind(boost::mem_fn(&MyHandler::onEvent),this, new FooEvent(5))));
}

void onEvent(const FooEvent * _event)
{
cout << _event->val << endl;
}

};

最终,我认为这行不通(它无法弄清楚整个 typeInfo 业务来创建 map 查找的键)

任何想法将不胜感激!

如果我以错误的方式解决这个问题,我将不胜感激提及替代方案。最后的目标当然是拥有一个可以轻松扩展其公共(public)接口(interface)及其数据成员的可装饰类型。我认为 Szymon 的东西是一个很好的起点,因为它似乎已经完成了第二部分。

提前感谢您的任何帮助。

最佳答案

也许一种选择是创建一个保留类型信息的模板化公共(public)函数,以及一个用于实际注册处理程序的虚拟保护函数。即:

class event_source {
protected:
struct EventAdapter {
virtual void invoke(EventBase *) = 0;
virtual ~EventAdapter() { }
};
template<typename EventParam>
struct EventAdapterInst : public EventAdapter {
boost::function<void(const EventParam &)> func_;

EventAdapterInst(const boost::function<void(const EventParam &)> &func)
: func_(func)
{ }

virtual void invoke(EventBase *eb) {
EventParam *param = dynamic_cast<EventParam *>(eb);
assert(param);
func_(*param);
}
};
virtual void register_handler(std::type_info param_type, EventAdapter *ea);
public:
template<typename EventParam>
void register_handler(const boost::function<const EventParam &> &handler)
{
register_handler(typeid(EventParam), new EventAdapterInst(handler));
}
};

派生类可以重写虚拟 register_handler 来做任何他们想做的事,而不会破坏模板函数的类型推断属性。

关于c++ - 在 C++ 中创建可装饰的有效事件处理类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6756155/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com