将成员函数作为参数传递

Passing member function as parameter

本文关键字:参数传递 函数 成员      更新时间:2023-10-16

所以我有这个函数:

void EventDispatcher::Subscribe(string eventName, void (*callback)(void *))
{
....
}

我正在尝试将类成员函数作为回调参数传递给那里。

typedef void (*method)(void*);
void EventTester::RunTests()
{
    _dispatcher = new EventDispatcher();
    Event eventOne("one");
    _dispatcher->Register("one", eventOne);
    method p = &onOne;
    _dispatcher->Subscribe("one", p);
}
void EventTester::onOne(void *args)
{
    std::cout<<"Event onen";
}

显然这不能编译,因为 onOne 不是静态的,而是成员函数。有没有办法让它以这种方式工作?

您可以在 C++03 或 std::bind 中使用 boost,在 C++11 中使用 std::function

typedef boost::function<void(void*)> func_type;
void EventDispatcher::Subscribe(const string& eventName, const func_type& func_)
{
  if ( ! func_.empty() ) {
    // you could call the function
    func_(NULL);
  }
}

//Register looks like in a member function of EventTester:
...
_dispatcher->Subscribe("one",boost::bind(&EventTester::onOne,this,_1));
...

我放弃了假设您有能力修改Subscribe签名的假设。如果没有,我的答案可能不适用。

正如您已经指出的,指向成员的指针(又名method)与普通函数指针不同。若要使用指向成员的指针,必须提供类实例以在方法执行过程中调用函数。

您可以修改Subscribe以显式接受指向成员的指针,这将需要一个额外的参数(class实例)。您需要Subscribe来存储函数指针和指向对象实例的指针。然后,这将要求将所有回调实现为指向成员的指针。

解决此问题的首选方法是使用 bindstd::bindboost::bind )。

您需要更改Subscribe函数以接收std/boost::function对象而不是显式函数指针。这将允许 Subscribe 方法的调用方传入任何callable对象(请参阅 std::function 文档中的示例)

然后,可以使用 bind 将类实例连接到方法指针。这将返回一个函子对象,该对象将同时保存指向成员的指针和指向类实例的指针。

有关如何使用绑定的示例,请参阅此链接