所以我有这个功能:
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不是静态的并且是成员函数。有没有办法让它以这种方式工作?
答案 0 :(得分:2)
你可以在C ++ 03中使用boost,或者在C ++ 11中使用std::bind
和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));
...
答案 1 :(得分:1)
我假设你有能力修改Subscribe
的签名。如果没有,我的答案可能不适用。
正如您已经指出的那样,指向成员的指针(又名method
)与普通函数指针不同。要使用指向成员的指针,必须提供类实例,以便在方法执行过程中调用函数。
您可以修改Subscribe
以显式接收指向成员的指针,这会产生额外的参数(class
实例)。您需要Subscribe
来存储函数指针和指向对象实例的指针。这将要求所有回调都作为指向成员的指针实现。
解决此问题的首选方法是使用bind
(std::bind
或boost::bind
)。
您需要更改Subscribe
函数以接受std/boost::function
对象而不是显式函数指针。这将允许Subscribe方法的调用者传入任何callable
对象(请参阅std::function文档中的示例)
然后,您可以使用bind
将类实例连接到方法指针。这将返回一个functor对象,它将执行指向成员指针和指向类实例的指针的工作。
有关如何使用bind的示例see this link