dan*_*jar 3 c++ events function-pointers function
对于事件管理器,我需要在向量中存储许多指向函数的指针,以便在触发事件时调用它们.(我将在本问题的最后提供EventFunction助手类的源代码.)
// an event is defined by a string name and a number
typedef pair<string, int> EventKey;
// EventFunction holds a pointer to a listener function with or without data parameter
typedef unordered_map<EventKey, vector<EventFunction>> ListEvent;
// stores all events and their listeners
ListEvent List;
Run Code Online (Sandbox Code Playgroud)
注册侦听器可以通过调用第一个或第二个函数来完成,具体取决于您是否希望接收其他数据.(此代码来自我的事件管理器类.)
public:
typedef void (*EventFunctionPointer)();
typedef void (*EventFunctionPointerData)(void* Data);
// let components register for events by functions with or without data parameter,
// internally simple create a EventFunction object and call the private function
void ManagerEvent::Listen(EventFunctionPointer Function, string Name, int State);
void ManagerEvent::Listen(EventFunctionPointerData Function, string Name, int State);
private:
void ManagerEvent::Listen(EventFunction Function, string Name, int State)
{
EventKey Key(Name, State);
List[Key].push_back(Function);
}
Run Code Online (Sandbox Code Playgroud)
该代码不起作用,因为我存储函数指针但不存储我的List中的成员函数指针.所有这些指针都应该是成员函数指针,因为类似的组件ComponentSound会"PlayerLevelup"在其成员函数的基础上监听事件,以便在ComponentSound::PlayerLevelup触发事件时发出良好的声音.
C++中的成员函数指针如下所示.
// ReturnType (Class::*MemberFunction)(Parameters);
void (ComponentSound::*PlayerLevelup)();
Run Code Online (Sandbox Code Playgroud)
问题是,任何组件类都应该能够侦听事件,但是在事件管理器中存储成员函数指针需要我指定监听类.正如您在示例中所看到的,我需要指定ComponentSound但事件管理器应该只有一个成员函数指向任何类的向量.
回答其中一个问题对我有很大帮助.
Component.)我试图保持我的问题一般,但如果你需要更多的信息或代码,请评论.
在我的成员函数指针向量中,我使用EventFunction而不是仅提供两种消息类型的指针.一个有,一个没有数据参数.
class EventFunction
{
private: EventFunctionPointer Pointer; EventFunctionPointerData PointerData; bool Data;
public:
EventFunction(EventFunctionPointer Pointer) : Pointer(Pointer), PointerData(NULL), Data(false) { }
EventFunction(EventFunctionPointerData PointerData) : PointerData(PointerData), Pointer(NULL), Data(true) { }
EventFunctionPointer GetFunction() { return Pointer; }
EventFunctionPointerData GetFunctionData() { return PointerData; } bool IsData() { return Data; }
void Call(void* Data = NULL){ if(this->Data) PointerData(Data); else Pointer(); }
};
Run Code Online (Sandbox Code Playgroud)
您可以使用函子来实现这一点。如果你在成员函数周围包裹一个函子,你可以用函子制作一个向量。一个函子看起来像这样:
template <class T> class MyFunctor
{
private:
T* ObjectPtr;
void (T::*MemberFunction) ();
public:
void operator () ()
{
return (*this->ObjectPtr.*this->MemberFunction)();
}
};
Run Code Online (Sandbox Code Playgroud)
所以基本上一个函子覆盖 () 运算符并返回存储在函子类中的成员函数。如果您希望函子使用不同的签名,则它们可能会非常复杂,但在本文中您可以获得更多信息。
http://www.codeproject.com/Articles/7112/Pointers-to-Member-Functions-and-Functors
你将不得不使用std::function.这是实现泛型回调的唯一方法.只要涉及函数指针而不是函数对象,它就不是通用的,永远不会是通用的,永远不能成为通用的.
unordered_map<string, vector<std::function<void()>>>
Run Code Online (Sandbox Code Playgroud)
函数指针很糟糕,不应该在C++中显式使用,只传递给像std::bind和std::function构造函数这样的模板,而成员函数指针则更糟糕.