기본 클래스 인수가있는 멤버 기능 포인터 파생 클래스 인수 수락
-
19-09-2019 - |
문제
그래서 저는이 이벤트 관리 수업을 진행하고 있습니다. 서명의 멤버 기능에 포인터 목록을 저장하고 있습니다. void (Event*)
이벤트는 현재 임의의 데이터를 저장하는 구조물 일뿐입니다.
typedef boost::function<void(Event*)> Callback;
typedef vector<Callback> CallbackList;
class EventManager
{
public:
template<typename T>
void RegisterEventHandler(const std::string& type, void (T::*handler)(Event*), T* obj)
{
mCallbackList[type].push_back(boost::bind(handler, obj, _1));
}
void DispatchEvent(const std::string& type, Event* evt)
{
for(CallbackList::iterator it = mCallbackList[type].begin(); it != mCallbackList[type].end(); ++it)
{
Callback callback = (*it);
callback(evt);
}
}
private:
hash_map<std::string, CallbackList> mCallbackList;
};
다른 버전의 이벤트를 도출 하고이 수업에 해당 멤버 기능에 포인터를 전달할 수 있다면 궁금합니다. 현재 나는 이것을 시도하고있다.
class MouseEvent : public Event
{
public:
int testMouseData1;
int testMouseData2;
int testMouseData3;
};
class HelloWorld
{
public:
void Display(MouseEvent* evt)
{
cout << "Hello, world!" << endl;
}
};
int main(void)
{
MouseEvent* evt = new MouseEvent();
HelloWorld* world = new HelloWorld();
eventManager->RegisterEventHandler("testType", &HelloWorld::Display, world);
return 0;
}
이것은 Xcode에서 다음 오류를 제공합니다.
오류 : 호출에 일치하는 기능 없음 '
EventManager::RegisterEventHandler(const char [9], void (HelloWorld::*)(MouseEvent*), HelloWorld*&)
'
기능 서명에서 파생 클래스를 기대하는 포인터를 안전하게 통과 할 수있는 방법을 알고 있습니까? 감사.
해결책
그래서 나는 나에게 효과가있는 것처럼 보이는 솔루션을 찾았지만 그것이 완전히 안전한 지 확실하지 않습니다. registereventhandler 메소드를 변경하여 동일한 유형으로 보내는 모든 기능 포인터를 캐스팅했습니다 ...
template<typename T1, typename T2>
void RegisterEventHandler(const String& type, T1 handler, T2* obj)
{
void (T2::*evtHandler)(Event*) = (void (T2::*)(Event*)) (handler);
mCallbackList[type].push_back(boost::bind(evtHandler, obj, _1));
}
이제 모든 것이 내가 원래 의도 한대로 작동하는 것 같습니다. 그러나 나는이 모든 것에 새로 익숙하지 않으므로 이것이 안전한 일인지 확실하지 않습니다. 이견있는 사람? 감사
다른 팁
프로토 타입이 "이벤트"유형을 기대하면 void Display(MouseEvent* evt)
함수는 "Event
"유형. 그러니 변경하십시오 void Display(Event *evt)
그런 다음 통화 내에서 다시 타이핑 할 수 있습니다. MouseEvent
, 발신자가 실제를 통과했다고 가정합니다 MouseEvent
, "Event
".
둘째, 나는 당신이 전화하는 방식에 다른 문제가있을 수 있다고 생각합니다. RegisterEventHandler
템플릿에 있지만 템플릿 유형을 지정하지 않기 때문입니다.