自己实现的Signal and slot

来源:互联网 发布:皓月屠龙翅膀进阶数据 编辑:程序博客网 时间:2024/05/16 17:52

我自己实现的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>

using namespace std;

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

原创粉丝点击