[英]C++ member function pointer, boost::signals
我有以下情况,(代码效果更好)
class Foo
{
private:
typedef boost::signal<void ()> Signal;
Signal signal;
public:
void Register_SignalFunction(const Signal::slot_type& slot);
void Unregister_SignalFunction(const Signal::slog_type& slot);
}
class OtherFoo
{
Foo foo;
public:
OtherFoo()
{
foo.Register_SignalFunction(&OnSignal) //I know I can't do this that is precisely my question.
}
void OnSignal(); //what to do when signal fires
}
所以问题是,如何将“成员函数”指针传递给Register方法。 还可以吗 我想要/需要的是某种代表注册系统,所以如果没有人可以指出正确的方向,我将不胜感激。 提前感谢。
您通常会使用Boost绑定:
foo.Register_SignalFunction(boost :: bind(&OtherFoo :: OnSignal,this));
这里发生了什么? :-)
信号的连接方法需要一个函子。 那是一个实现()运算符的对象。 bind获取函数指针(指向自由函数或成员函数),并返回具有正确签名的函子。
另请参阅此处:
使用Boost :: Signals进行C ++事件的完整示例
和这里:
boost :: function和boost :: bind如何工作
要断开信号存储,请将返回值从connect连接到:
boost::signals::connection
然后调用该方法的断开连接。
通常,您会:
void Register_SignalFunction(const boost::function<void()> &slot) {
signal += slot;
}
或者,作为内联函数:
template<typename T>
void Register_SignalFunction(T &slot) {
signal += slot;
}
通过删除间接boost::function
具有的层,后者可能会稍微更有效率-但仅假设boost::signal
在内部不使用boost::function
(可能会使用)。 因此,请使用您喜欢的任何一种。
如果有人想举一个完整的例子:
#include <iostream>
#include <boost/signals2/signal.hpp>
#include <boost/bind.hpp>
#include <boost/optional/optional_io.hpp>
#define registerEvent_(A) registerEvent(boost::bind(A, this, _1, _2))
struct A
{
typedef boost::signals2::signal<int (int &, int &)> EventSignal;
typedef EventSignal::slot_type SlotType;
void registerEvent(const SlotType & slot);
void triggerAll(int& a1, int& a2);
EventSignal signal_;
};
void A::registerEvent(const SlotType & slot) { signal_.connect(slot); }
void A::triggerAll(int& a1, int& a2) {std::cout << signal_(a1, a2) << "\n";}
struct B : public A
{
B();
int myFunc(int& a1, int& a2);
};
B::B() {
#ifdef WITHMACRO
registerEvent_(&B::myFunc);
#else
registerEvent(boost::bind(&B::myFunc, this, _1, _2));
#endif
}
int B::myFunc(int& a1, int& a2) { return a1 + a2 + 1; }
int main()
{
int a1 = 2;
int a2 = 3;
B b;
b.triggerAll(a1, a2);
}
我尝试了很多之后就可以正常工作了,下面是代码:
GraphicsDeviceManager
{
private:
typedef boost::signal<void ()> DeviceLost;
DeviceLost deviceLost;
public:
Register_DeviceLostHandler(const boost::function<void ()> &handler)
{
deviceLost.connect(slot);
}
Unregister_DeviceLostHandler(const boost::function<void ()> &handler)
{
//deviceLost.disconnect(slot);
}
}
class GameBase
{
private:
GraphicsDeviceManager* graphics;
public:
GameBase()
{
graphics = new GraphicsDeviceManager();
graphics->Register_DeviceLostHandler(boost::bind(&GameBase::OnDeviceLost, this));
}
void OnDeviceLost()
{
//do some stuff
}
}
这段代码可以正常工作,但有一个例外,如果我取消对deviceLost.disconnect(handler)语句的注释,我将收到类似以下的编译错误:错误C266“ boost :: operator ==”:4个重载具有相似的转换。
那么,为什么会这样呢? 您是否知道其他方法来完成我正在尝试的工作?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.