C++模板实现模块间参数传递及回调之三

本文介绍了如何使用C++模板创建一个回调管理器,以实现模块之间的解耦。文中提供了代码示例,包括注册回调、执行回调以及不同类型的回调执行方式,如直接执行和线程回调。此外,还讨论了回调管理器的实现细节,包括回调的存储、执行和删除策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

1 回调管理器

利用上面的技术可以实现一个回调管理器,使用这个东西可以使互相关联的模块解耦。

1.1 代码示例

typedef CCallbackManager<std::string> CallbackManager;

CallbackManager manager;

void Test0()

{

  int a = 9;

}

void Test1(int i)

{

  int a = 9;

}

Struct xyz

{

Int Menberfunc(bool);

};

Xyz *p = new xyz;

manager.RegisterCallback("msg0",CreateCallback(Test0));

    manager.RegisterCallback("msg1",CreateCallback(Test1));

manager.RegisterCallback("msg2",CreateCallback(p,&Xyz ::Menberfunc));

manager.ExecCallback("msg0");

manager.ExecCallback("msg1",3);

manager.ExecCallback("msg2",false);

1.2 实现

实现一个回调管理器很简单,但是如果考虑到void*类型的回调就相当的麻烦,再考虑到回调的执行线程就更加麻烦,先来看回调管理器的声明:

template<class MSG,class Method = CallbackFunc *,class Exec = CDirectExec

  ,template<class> class Deleter = CallbackDeleter>

  class CCallbackManager

  {

  private:

      typedef typename std::map<MSG,std::vector<Method> >::iterator iterType;

      typedef typename std::vector<Method>::size_type sizeType;

  public:

      CCallbackManager(){}

      ~CCallbackManager(){Clear();}

      void Clear()

      {

          exec.Clear();

          for(iterType it = m_callbacks.begin();it!=m_callbacks.end();++it)

          {

              std::vector<Method> &callback = it->second;

              for( sizeType i = 0;i<callback.size();++i)

              {

                  Deleter<Method>::Delete(callback[i]);

              }

          }

          m_callbacks.clear();

      }

      void RegisterCallback(MSG msg,Method m){m_callbacks[msg].push_back(m);}

    

      template<class T1,class T2,class T3>

      void ExecCallback(MSG msg,TRAITS(T1) t1,TRAITS(T2) t2,TRAITS(T3) t3)

      {

          std::vector<Method> &callbacks = m_callbacks[msg];

          for(sizeType i = 0;i<callbacks.size();++i)

          {

              exec.Execute(callbacks[i],t1,t2,t3);

          }

      }

      

     

  private:

      Exec exec;

      std::map<MSG,std::vector<Method> > m_callbacks;

  };

这里只给出了3个参数的回调调用方法,详细代码可参考附录,第一个模板参数是MSG,这是消息的类型,可以是int, string或其他可比较的类型,第二个参数是回调方法,可以是CallbackFunc *void*,第三个参数是回调执行器,用来实现直接回调或线程回调,第四个参数是回调释放器,加入这个是由于释放行为对于CallbackFunc *void*是不同的。

CDirectExec的实现:

  class CDirectExec

  {

  public:

      void Execute(CallbackFunc *p)

      {

          p->Excute();

      }

      template<class T1>

      void Execute(CallbackFunc *p,T1 &t1)

      {

          ExcuteCallback(p,t1);

      }

      template<class T1,class T2>

      void Execute(CallbackFunc *p,T1 &t1,T2 &t2)

      {

          ExcuteCallback(p,t1,t2);

      }

      template<class T1,class T2,class T3>

      void Execute(CallbackFunc *p,T1 &t1,T2 &t2,T3 &t3)

      {

          ExcuteCallback(p,t1,t2,t3);

      }

      template<class T1,class T2,class T3,class T4>

      void Execute(CallbackFunc *p,T1 &t1,T2 &t2,T3 &t3,T4 &t4)

      {

          ExcuteCallback(p,t1,t2,t3,t4);

      }

      template<class T1,class T2,class T3,class T4,class T5>

      void Execute(CallbackFunc *p,T1 &t1,T2 &t2,T3 &t3,T4 &t4,T5 &t5)

      {

          ExcuteCallback(p,t1,t2,t3,t4,t5);

      }

      void Clear() {}

      void Remove(CallbackFunc *p) {}

  };

通过线程来实现回调的类需要你自己实现,只要提供和CDirectExec相同的接口皆可。

假设你自己实现了一个通过线程队列来执行回调的类CThreadExec,那么你可以这么定义一个使用线程的回调管理器:

typedef CCallbackManager<int,CallbackFunc*,CThreadExec>  CallbackManager;

 

 

如果对代码有兴趣的人可以到我上传的资源里找。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值