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

来源:互联网 发布:星际皆知我爱你百度云 编辑:程序博客网 时间:2024/05/24 02:36


原文链接: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");
}
原创粉丝点击