C++:作为事件回调的类成员函数
我正在尝试向我的项目添加一个简单的消息传递系统,其中事件可以由函数调用,这将导致注册到该事件的所有回调被调用。
现在,执行此操作的逻辑方法是使用函数指针。可以轻松地将指向所需回调函数的指针传递给事件管理器以进行注册。事件回调函数始终返回 int
并采用 void*
作为参数。
但是,我不想将静态全局函数注册为我的事件回调 - 我想使用类成员函数来实现。
是否可以使用 C++ 来完成此任务?存储和调用指向不同类但具有相同函数头的成员函数的指针。
如果这是不可能的,您对我如何解决这个问题有什么建议吗?我真的很想将事件监听器直接添加到我的类中。
I'm trying to add a simple messaging system to my project, where events can be invoked by a function, which will lead to all callbacks registered to that event being called.
Now, the logical way to do this is using function pointers. It would be easily possible to pass the pointer to the desired callback function to the events manager, for registering. An event callback function would always return an int
and take a void*
as argument.
However I don't want to register static global functions as my event callbacks - I'd like to do it with class member functions.
Is it even possible to accomplish this with C++? Storing and calling pointers to member functions of different classes but with the same function header.
If this is not possible, do you have any suggestions on how I could work around this? I'd really like to add event listeners directly to my classes.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
是的,这是可能的。 C++0x 有处理此问题的
function
类< /a>,正如其他人指出的那样,Boost 具有类似的功能。您也可以自己编写,但语法不适合胆小的人:
这演示了一种以不透明的方式处理自由函数和成员函数的方法。这是一个简单的示例,可以通过多种方式使其更加通用和健壮。我建议您访问以下页面以获取语法帮助:
http://www.newty.de/fpt /index.html
http://www.parashift .com/c++-faq-lite/pointers-to-members.html
我还建议查看此内容以获取更多想法:
http://www.codeproject.com/KB/cpp/FastDelegate.aspx
Yes it is possible. C++0x has the
function
class that handles this, and as others have pointed out Boost has similar facilities.You can also roll your own, but the syntax is not for the faint of heart:
This demonstrates a way of handling both free functions, and member functions in an opaque way. This is a simple example, and can be made more generic and robust in a number of ways. I'd refer you to these pages for syntax help:
http://www.newty.de/fpt/index.html
http://www.parashift.com/c++-faq-lite/pointers-to-members.html
I'd also recommend looking at this for more ideas:
http://www.codeproject.com/KB/cpp/FastDelegate.aspx
当然有可能!看看 Boost.Signal2 和 Boost.Bind。
Boost.Signal2 基本上实现了一个信号和槽系统,这正是您所需要的。
然后,您可以使用
boost::bind
(它是std::bind1st
和std::bind2nd
的泛化)来获取函数对象包装器基本上任何你能想到的东西(在你的例子中,成员方法)。真的很强大。请参阅此官方Boost 教程。
Of course it's possible ! Have a look at Boost.Signal2 and Boost.Bind.
Boost.Signal2 basically implements a signal and slots system which is exactly what you need.
Then, you can use
boost::bind
which is a generalization ofstd::bind1st
andstd::bind2nd
to get function object wrappers to basically anything you can think of (in your case, member methods). It's really powerful.See this official boost tutorial.
这是我做这样的工作的不太好的尝试:
首先,您需要一个基本事件处理程序类,现在我们将其称为 EvtHandler:
然后,每个应该以某种方式处理事件的类都应该从此类派生,并且它们可以实现新的只要它们返回相同的数据类型(在本例中为void)并接收相同的参数(在本例中为Event),就可以尽可能多地执行函数。像这样:
然后我为每个特殊事件实现了消息中心,它必须注册侦听器并在需要时分派事件:
然后您可以将 EvtHandler 注册到这个特定的消息中心!
但这一点也不好,只是想分享一下!抱歉打扰了,哈哈!
Here is my not-so-good attempt for doing a job like that:
First of all you need a base event handler class, well let's call it EvtHandler for now:
Then every class that is supposed to handle events in a way, should derive from this class, and they can implement new functions as much as they want as far as they return the same data type (void in this case) and recieve the same paramteres (Event in this case). Like this:
Then I implemented message centers for each special event, which had to register listeners and dispatch events when needed:
Then you could register your EvtHandlers to this particular message center for example!
But once again this is not good at all, just thought I would share! Sorry for the mess, haha!
我不完全确定你想要存档什么,但也许你应该看看 Boost Signals2
如果您想创建某种信号/槽机制,它会非常有帮助。
I am not completely sure what you want to archive but maybe you should look at Boost Signals2
It is quite helpful if you want to create some sort of Signal/Slot mechanism.
不,这是不可能的(除非您使用 .net 执行 c++/cli)。
现在,您仍然可以创建静态函数,将一个对象作为参数传递给它们,它们唯一要做的就是调用该对象上的成员函数。 (实际上首先需要演员阵容)。
No, it is not possible (unless you do c++/cli with .net).
Now, you can still create static functions, pass them an object as a parameter, and the only thing that they'll do is call your member function on that object. (Actually a cast will be required first).
我最接近的做法是将静态成员函数注册为回调。除了事件处理程序发送的参数之外,静态成员还接受对象(this)指针作为参数,并使用 this 来调用成员函数。
向您的处理程序注册
myClass::callback
和this
。如果您的返回内容受到限制,您可能需要将其包装在 arg 引用的结构中。The closest that I have managed is to register a static member function as the callback. The static member takes the object (this) pointer as an argument in addition to the arguments sent by the event handler and uses this to call the member function.
Register
myClass::callback
andthis
with your handler. You may need to wrap this in the structure that arg references if you are restricted in what can be returned.我正在将 lukes 答案与 SWIG 一起使用,因为 SWIG 不支持所有 C++11 功能...这可能可以通过 Parsa Jamshidis 方法进一步改进。
我修改了它以涵盖更多情况(可变数量的参数和可变返回类型):
I am using lukes answer with SWIG because SWIG does not support all C++11 features... This probably can be improved even further with Parsa Jamshidis approach.
I modified it to cover even more cases (variable amount of arguments and variable return type):