您的位置:首页 > 编程语言 > C语言/C++

用标准C++实现信号与槽机制

2013-04-06 22:42 363 查看



原文链接:http://blog.csdn.net/ilvu999/article/details/7948429

用标准C++实现信号与槽机制

信号对象保存参数,以及槽对象列表.

对信号而言槽的类型只与函数指针的参数类型相关.

槽保存被绑定的对象,以及需要转发调用的函数指针.

只有绑定时才知道被绑定对象的类型.

绑定时,根据被绑定的对象由模板动态生成槽对象.

构建一个槽时,被绑定的对象的类型的信息,作为模板参数生成槽对象.

#include <algorithm>
#include <iostream>

#include <vector>

using namespace std;

template<class T1>

class SlotBase

{

public:

virtual void Exec(T1 param1) = 0;
virtual ~SlotBase();

};

template<class T, class T1>

class SlotImpl : public SlotBase<T1>

{

public:

SlotImpl(T* pObj, void (T::*func)(T1) )

{

m_pObj = pObj;

m_Func = func;

}

void Exec( T1 param1)

{

(m_pObj->*m_Func)(param1);

}

private:

T* m_pObj;

void (T::*m_Func)(T1);

};

template<class T1>

class Signal

{

public:

template<class T>

void Bind(T* pObj, void (T::*func)(T1))

{

m_pSlotSet.push_back( new SlotImpl<T,T1>(pObj,func) );

}

~Signal()

{

for(int i=0;i<(int)m_pSlotSet.size();i++)

{

delete m_pSlotSet[i];

}

}

void operator()(T1 param1)

{

for(int i=0;i<(int)m_pSlotSet.size();i++)

{

m_pSlotSet[i]->Exec(param1);

}

}

private:

vector< SlotBase<T1>* > m_pSlotSet;

};

#define Connect( sender, signal, receiver, method) ( (sender)->signal.Bind(receiver, method) )

class A

{

public:

void FuncOfA(int param)

{

printf("A::FuncOfA(%d)\n", param);

}

};

class B

{

public:

void FuncOfB(int param)

{

printf("B::FuncOfB(%d)\n", param);

}

};

class C

{

public:

C()

{

m_Value = 0;

}

void SetValue(int value)

{

if(m_Value != value)

{

m_Value = value;

ValueChanged(m_Value);

}

}

public:

Signal<int> ValueChanged;

private:

int m_Value;

};

int testsignal()

{

A* pA = new A;

B* pB = new B;

C* pC = new C;

Connect(pC, ValueChanged, pA, &A::FuncOfA);

Connect(pC, ValueChanged, pB, &B::FuncOfB);

pC->SetValue(10);

pC->SetValue(5);

pC->SetValue(5);

delete pC;

delete pB;

delete pA;

scanf("%*s");

}


下面是原文

以前一直以为用标准C++无法实现类似委托或者信号与槽的机制。
还写过一篇BLOG http://www.cnitblog.com/luckydmz/archive/2009/11/23/62785.html

看来我还是“太年轻”,无知啊。

#include <algorithm>

#include <iostream>

#include <vector>

using namespace std;

template<class T1>

class SlotBase

{

public:

virtual void Exec(T1 param1) = 0;

};template<class T, class T1>

class SlotImpl : public SlotBase<T1>

{

public:

SlotImpl(T* pObj, void (T::*func)(T1) )

{

m_pObj = pObj;

m_Func = func;

}

void Exec( T1 param1)

{

(m_pObj->*m_Func)(param1);

}

private:

T* m_pObj;

void (T::*m_Func)(T1);

};template<class T1>

class Slot

{

public:

template<class T>

Slot(T* pObj, void (T::*func)(T1))

{

m_pSlotBase = new SlotImpl<T,T1>(pObj, func);

}

~Slot()

{

delete m_pSlotBase;

}

void Exec(T1 param1)

{

m_pSlotBase->Exec(param1);

}

private:

SlotBase<T1>* m_pSlotBase;

};template<class T1>

class Signal

{

public:

template<class T>

void Bind(T* pObj, void (T::*func)(T1))

{

m_pSlotSet.push_back( new Slot<T1>(pObj,func) );

}

~Signal()

{

for(int i=0;i<(int)m_pSlotSet.size();i++)

{

delete m_pSlotSet[i];

}

}

void operator()(T1 param1)

{

for(int i=0;i<(int)m_pSlotSet.size();i++)

{

m_pSlotSet[i]->Exec(param1);

}

}

private:

vector< Slot<T1>* > m_pSlotSet;

};#define Connect( sender, signal, receiver, method) ( (sender)->signal.Bind(receiver, method) )

class A

{

public:

void FuncOfA(int param)

{

printf("A::FuncOfA(%d)\n", param);

}

};class B

{

public:

void FuncOfB(int param)

{

printf("B::FuncOfB(%d)\n", param);

}

};class C

{

public:

C()

{

m_Value = 0;

}

void SetValue(int value)

{

if(m_Value != value)

{

m_Value = value;

ValueChanged(m_Value);

}

}

public:

Signal<int> ValueChanged;

private:

int m_Value;

};int main()

{

A* pA = new A;

B* pB = new B;

C* pC = new C;

Connect(pC, ValueChanged, pA, &A::FuncOfA);

Connect(pC, ValueChanged, pB, &B::FuncOfB);

pC->SetValue(10);

pC->SetValue(5);

pC->SetValue(5);

delete pC;

delete pB;

delete pA;

scanf("%*s");

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: