2011-08-23 50 views
2

我有以下的情况,(在代码更好)C++成员函数的指针,升压::信号

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 
    } 

所以,问题是,如何通过一个“成员函数”指针寄存器的方法。另外,这是好吗?我想/需要的是某种委托注册系统,所以如果任何人都无法指出我的方向,我会很感激。提前Thanx。

回答

1

通常你要么做:

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(它很可能)。所以,使用你喜欢的任何一个,真的。

3

您通常使用升压绑定:

foo.Register_SignalFunction(升压::绑定(& OtherFoo :: OnSignal,这个));

这是怎么回事? :-)

信号的连接方法需要一个仿函数。这是一个实现()运算符的对象。绑定需要函数指针(或者释放函数或者成员函数)并且返回一个具有正确签名的函子。

而且在这里看到:

Complete example using Boost::Signals for C++ Eventing

这里:

how boost::function and boost::bind work

要断开信号存储返回值从连接成:

boost::signals::connection 

而且然后拨打断开ct方法。

+0

每当我尝试做一些类似foo我得到这个错误。Register_SignalFunction(boost :: bind(&OtherFoo :: OnSignal,this));错误C2678:二进制'==':找不到操作符找到类型为'const boost :: slot '的左手操作数是不可接受的转换)\t f:\ development \ boost_1_41_0 \ boost \ function_equal.hpp Indigen_Framework – Yoss

+0

@Yoss:我认为你的Signal typedef必须是公开的。除此之外,请发布一个最小的可编译示例。您当前的代码中存在拼写错误,例如Signal :: slog_type ... –

0

我得到了它想要了很多工作后,下面的代码:

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 
     } 
} 

以及此代码的工作,因为它应该是一个例外,如果我unccomment的deviceLost.disconnect(处理器)语句,我收到编译错误,如: 错误C266“boost :: operator ==”:4重载有类似的转换。

那么,为什么会发生这种情况呢?你知道任何其他方式来完成我想要的吗?

+0

Ps:对不起,如果您看到错别字,我输入了代码,我没有从Visual Studio复制/粘贴。 – Yoss

+0

你不会那样断开连接。你的注册函数应该返回一个boost :: signals :: connection,然后你使用它来断开连接。查看我的答案和Boost信号文档。 –

0

如果有人想要一个完整的例子:

#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); 
}