0

所以我有这个功能:

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 one\n";
}

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

4

2 回答 2

2

std::bind您可以在 C++03或C++11 中使用 boost 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));
...
于 2013-09-06T19:45:14.237 回答
1

我假设您有能力修改Subscribe. 如果不是,我的回答可能不适用。

正如您已经指出的,指向成员的指针(又名method)与普通函数指针不同。要使用指向成员的指针,您必须提供类实例来调用函数作为方法执行的一部分。

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

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

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

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

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

于 2013-09-06T19:46:12.697 回答