用标准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 " );
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值