2011-03-01 77 views
2

我创建简化描述的事件处理系统,通过以下类需要帮助避免向下转型

IEventType - containing string name and hashed int value of the name for fast search 
IEventData - data send along with a triggered event 
EventManager - containing a std::map of <int, boost::signals2< bool(boost::shared_ptr<IEventData>) > 

(有一些其他listeneres过了LUA脚本外活动多,但我认为是无关紧要的了)

实际的问题是: 当我得出一个IEventData,让我们说:

class EData_WriteToConsole : IEventData 
{ 
    std::string text; 
    int layer; 
    ... 
} 

然后我注册一些成员函数信号:

OnWriteToConsole(boost::shared_ptr<IEventData>){ ... } 
m_EventManager->AddListener(boost::bind(&Console::OnWriteToConsole, m_Console, _1)); 

,然后使用eventmanager进行的TriggerEvent功能

boost::shared_ptr<EData_WriteToConsole> eventData(new EData_WriteToConsole("Text..", 1)); 
m_EventManager->TriggerEvent(eventData); 

终于我的事件被触发: 但由于OnWriteToConsole只接收一个基类IEventData PTR我无法访问EData_WriteToConsole特定事件的数据。

所以我需要贬低IEventData的boost :: shared_ptr指向,到派生类EData_WriteToConsole。

我目前被卡住了,因为我的大脑在最后几天没有得到足够的睡眠,我无法想象没有向下转换的解决方案。 有没有办法解决这个问题,我可以以某种方式重构我的班级层次结构,所以我不需要上传?(我想创建一个std :: map数据作为eventdata传递,因此接收函数可以搜索它需要的东西,但对我来说似乎很慢并且很愚蠢)请帮忙

+1

从基类指针到派生类指针的转换是*向下转换*,不是向上转换。继承树的根源在顶端,责怪计算机科学家,他们没有足够的新鲜空气...... – 2011-03-01 10:00:24

+0

谢谢我纠正它,我的错误。我现在感到很蠢:/ – cppanda 2011-03-01 10:08:14

回答

1

你可以把虚拟方法放在IEventData接口,例如actionEvent()在派生类中实现以调用操作事件所需的任何内容?

它会限制你一点,如果事件需要以几种不同的方式进行操作。

+0

我实际上是在lua eventlisteners和eventdata上做这个事情,但是对于C++ eventmanger而言,由于boost :: signals2,这是不可能的,因为它会调用所有插槽本身。我不得不删除所有的boost :: signals2东西来启用这个功能。但如果真的没有其他解决方案的话,我愿意 – cppanda 2011-03-01 09:04:14