【问题标题】:C++ Passing a member function as a callbackC ++将成员函数作为回调传递
【发布时间】:2013-06-12 16:28:19
【问题描述】:

我正在尝试创建一个用于游戏的非常简单的事件系统。我有一个看起来像这样的 EventManager 类:

typedef std::function<void(IEvent* event)> CallbackType;

class EventManager
{
public:
    void AddListener(const std::string eventName, IEventListener* listener)
    {
        CallbackType callback = std::bind(&IEventListener::HandleEvent, listener, std::placeholders::_1);

        listeners[eventName].push_back(callback);
    }

    void AddListener(const std::string eventName, CallbackType callback)
    {
        // ...
    }

    void TriggerEvent(IEvent* event)
    {
        for (CallbackType callback : listeners[event->GetName()])
        {
            callback(event);
        }
    }
private:
    std::map<std::string, std::vector<CallbackType>> listeners;
}

第一个 AddListener 函数完美运行。 TriggerEvent 函数调用 HandleEvent 函数,该函数由扩展我的 IEventListener 接口的每个类实现。

我真的希望能够将回调传递给第二个 AddListener 函数。然后,该回调将像以前一样在 TriggerEvent 函数中被调用。我可以传入一个使用 std::bind 构造的回调,这很有效。例如:

eventManager->AddListener("WindowResize", std::bind(&MyClass::MemberFunction, this, std::placeholders::_1));

其中 MyClass 扩展了 IEventListener 接口。但是,我真的希望能够只传递一个简单的函数指针:

eventManager->AddListener("WindowResize", this, &MyClass::MemberFunction);

这可能吗?

编辑

对于任何感兴趣的人,我写了几个我认为可以让事情变得更简洁的宏。

#define MEMBER_CALLBACK(funPtr) \
std::bind(&funPtr, this, std::placeholders::_1)

#define MEMBER_CALLBACK_WITH_INSTANCE(funPtr, instancePtr) \
std::bind(&funPtr, instancePtr, std::placeholders::_1)

现在我可以通过以下方式订阅活动:

eventManager->AddListener("EventName", MEMBER_CALLBACK(MyClass::MemberFunction));

【问题讨论】:

  • 你可以(它不会是一个“简单函数指针”,而是一个成员函数指针),但我怀疑它会不会好:std::bind 更灵活,需要用户思考关于例如this 的生命周期与 eventManager 的生命周期相比。
  • 感谢您的编辑。这是我正在寻找的关于如何准确执行此操作的简单示例。完美!

标签: c++ function-pointers member-function-pointers


【解决方案1】:

你不能传递一个简单的函数指针,因为MyClass::MemberFunction 不是一个简单的函数。 std::bind() 之所以有效,是因为它将MyClass 的实例与对成员函数的引用相关联。如果没有这些信息,成员函数将无法访问实例的数据。

【讨论】:

  • 谢谢。我决定使用宏。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多