2011-03-01 103 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