我自己实现的Signal Slot库地址:http://gitorious.org/raylib/raylib/blobs/master/SignalSlot.hpp
C++中不同于.net和Java,并没有确定的“事件”的实现。就像.net的委托,Java的listener,都是比较好的实现。
早期的C++事件实现基于消息映射,或者消息循环。经常是一个消息,一大片switch,这样代码过于集中,而且没有一个像.net一样的事件发出者,并不怎么样。
当然,对于事件的实现,基本上有两大类,一种是“查表法”(消息映射,.net的事件,signal slot都属于这类)。另一种是虚函数法(VCL是吗?没用过;呵呵)。虚函数法的问题是,如果这个事件被处理的概率很小,那他内部消耗还是很大的(内存等)。
最近自己实现了一个Signal 和 Slot ,大家可以看看,对比一下,和消息映射有什么区别。
<code>#include <iostream>
#include “SignalSlot.hpp”
#include “SmartPtr.hpp”
#include <Windows.h>
usingnamespacestd;
class SignalTest
{
public:
SignalTest()
{
this->m_overflowSlot = OverFlowSignal.connect(this,&SignalTest::catchOverFlow);
this->m_overflowSlot.enable();
this->m_overflowSlot_const
= OverFlowSignal.connect(this,&SignalTest::catchOverFlowC);
this->m_overflowSlot_const.enable();
}
void increase()
{
static int i = 0;
++i;
if(i>20)
{
i = 0;
OverFlowSignal.emit();
}
}
void catchOverFlow()
{
cout<<”Catch Over Flow Member”<<endl;
}
void catchOverFlowC()const
{
cout<<”Catch Over Flow Const”<<endl;
}
RayLib::SignalV0 OverFlowSignal;
private:
RayLib::Slot m_overflowSlot;
RayLib::Slot m_overflowSlot_const;
};
void CatchOverFlowStatic()
{
cout<<”Catching Over Flow Static”<<endl;
}
int main()
{
SignalTest t1;
RayLib::Slot sl = t1.OverFlowSignal .connect(CatchOverFlowStatic);
sl.enable();
while(1)
{
t1.increase();
Sleep(100);
}
return 0;
}</code>
这里只是个测试。作为SignalTest类,他有可能发布一个signal(消息,事件,随便别的名字都行),叫OverFlowSignal。关注这个Signal的其他部分,都可以订阅他,也就是connect操作。。connect可以有静态的方法,也可以有类的成员方法。connect操作返回一个Slot(事件的响应者的句柄。。可以这么理解吧)。这个Slot可以disable,enable,destory。当Signal发出时,并且Slot也enable的情况下,会调用相应的处理函数。
当然,和.Net 一样,Signal是一对多的,一个Signal可以对应N个Slot。
这样就可以很有效的降低类之间的耦合。一个类如果想发出事件,只需要创建个Signal,然后再emit(发射)它,就行了。
另一个类如果关注这个时间,那就创建个Slot ,connect这个signal就行了。。
这样子,事件的发出方,和接收方可以达到互相不依赖的目的。
当然,最好是用Git都下来。编译。因为我这个SignalSlot还依赖于智能指针。呵呵。
呵呵,最近放假,想实现一些C++的基础类库,已经实现了智能指针,Signal 和Slot了。。
有兴趣一块写的可以回帖。
项目托管地址:http://gitorious.org/raylib