c++ - 将函数指针存储到任何成员函数

标签 c++ function events function-pointers

我的事件经理

对于事件管理器,我需要在 vector 中存储许多指向函数的指针,以便在触发事件时调用它们。 (我会在本题最后提供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;

可以通过调用第一个或第二个函数来注册监听器,具体取决于您是否要接收其他数据。 (此代码来 self 的事件管理器类。)

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);
  }  

成员函数指针

该代码不起作用,因为我在我的列表中存储了函数指针而不是成员函数指针。所有这些指针都应该是成员函数指针,因为像 ComponentSound 这样的组件会监听事件"PlayerLevelup"及其成员函数 ComponentSound::PlayerLevelup如果事件被触发,播放美妙的声音。

C++ 中的成员函数指针如下所示。

// ReturnType (Class::*MemberFunction)(Parameters);
void (ComponentSound::*PlayerLevelup)();

问题是,任何组件类都应该能够监听事件,但是在事件管理器中存储成员函数指针需要我指定监听类。正如您在示例中看到的,我需要指定 ComponentSound但是事件管理器应该简单地有一个指向任何类的成员函数指针 vector 。

问题

其中一个问题的答案会对我有很大帮助。

  • 如何在事件管理器的 vector 中存储指向任何成员函数的函数指针? (也许所有的监听函数都继承自一个抽象类 Component 会有所帮助。)
  • 如何以另一种方式设计事件管理器以实现目标功能? (我想对消息使用字符串和整数键。)

我尽量让我的问题笼统,但如果您需要更多信息或代码,请发表评论。

作业

在我的成员函数指针 vector 中,我使用 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(); }
};

最佳答案

您将不得不使用 std::function .这是实现通用回调的唯一方法。一旦涉及函数指针而不是函数对象,它就不是泛型的,永远不会是泛型的,也永远不能成为泛型的。

unordered_map<string, vector<std::function<void()>>>

函数指针是不好的,永远不应该在 C++ 中显式使用,只能传递给像 std::bind 这样的模板。而std::function的构造函数和成员函数指针就更糟了。

关于c++ - 将函数指针存储到任何成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12988320/

相关文章:

C++ 继承 - 覆盖函数,包括使用 "::"s、.h 文件和 .cpp 文件

javascript - onClick问题的多种功能

javascript - this.evaluate 使用函数参数来实现大型可重用函数

html - 触摸事件让我抓狂

c++ - 触发 COM 事件时调用 Lock()/Unlock() 的目的是什么?

c++ - 从 _bstr_t 到 std::string 的转换

c++ - Gcc 隐藏来自包含的静态库的符号的可见性

c++ - 为什么编译器对原始/标准数组而不是 vector 使用 XMM 寄存器?

PHP 5.3 lambda 匿名函数不工作

node.js - 如何从 node.js 应用程序永久监听智能合约中的事件?