传递成员函数作为参数

时间:2013-09-06 19:23:51

标签: c++

所以我有这个功能:

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不是静态的并且是成员函数。有没有办法让它以这种方式工作?

2 个答案:

答案 0 :(得分:2)

你可以在C ++ 03中使用boost,或者在C ++ 11中使用std::bindstd::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));
...

答案 1 :(得分:1)

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

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

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

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

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

然后,您可以使用bind将类实例连接到方法指针。这将返回一个functor对象,它将执行指向成员指针和指向类实例的指针的工作。

有关如何使用bind的示例see this link