用 C++ 实现 C# 中的 委托/事件 (3-functor0)

前两天看程序员杂志
看到关于 C# 中的委托/事件
觉得用起来好像是挺方便的
本人热衷于 C++
想想用 C++ 来模拟似乎也可以
于是就有了下面的代码...
(VC6 不支持偏特化 本人工作环境就是 VC6 痛啊~~~)

没有返回值的函数用 delegate
否则就用 delegate_rt
functor 也一样 functorN/functorN_rt
delegate 的模板参数可以是函数指针(非成员函数)
也可以是 functor
还可以是 delegate
functor 可用 make_functor/make_functor_rt 来生成
要是有偏特化 就可以去掉讨厌的 _rt 了 :(

关于委托 boost里有现成的
不过可能 VC6 里用不了

这些代码旨在个人研究
如果大家发现其中问题 希望能指出

//filename: functor0.h
#ifndef _FUNCTOR0_H_
#define _FUNCTOR0_H_


class functor0
{
  class deleobject
  {
  };
  typedef void (*func_pt)();
  typedef void (deleobject::*mem_func_pt)();
  typedef void (deleobject::*cmem_func_pt)() const;
  functor_base<deleobject,
    func_pt, 
    mem_func_pt, 
    cmem_func_pt> base;
  
  public: 
    functor0() : base() {}
    functor0(func_pt pf) : base(pf) {}
    template<typename T> 
      functor0(const T *pObject, void (T::*fp)()) :
        base((const deleobject*)(pObject), 
          *((mem_func_pt*)(&fp))) {}
    template<typename T> 
      functor0(const T &pObject, void (T::*fp)()) :
        base((const deleobject*)(pObject), 
          *((mem_func_pt*)(&fp))) {}
    template<typename T> 
      functor0(const T *pObject, void (T::*fp)() const) :
        base((const deleobject*)(pObject), 
          *((cmem_func_pt*)(&fp))) {}
    template<typename T> 
      functor0(const T &pObject, void (T::*fp)() const) :
        base((const deleobject*)(pObject), 
          *((cmem_func_pt*)(&fp))) {}
  bool operator !=(const functor0& rhs) const { return !(*this == rhs); }
  bool operator ==(const functor0& rhs) const
  {
    return base == rhs.base;
  }
  bool operator ==(const void* rhs) const
  {
    return base == rhs;
  }
  functor0& operator =(const functor0& rhs)
  {
    base = rhs.base;
    return *this;
  }
  void operator()() const
  {
    if (base.m_pObject == NULL)
      (*base.m_pf)();
    else
      (base.m_pObject->*(base.m_pmf))();
  }
};


inline functor0 make_functor(void (*fp)())
{
  return functor0(fp);
}

template <class T>
inline functor0 make_functor(const T* tp, void (T::*fp)())
{
  return functor0(tp, fp);
}

template <class T>
inline functor0 make_functor(const T* tp, void (T::*fp)() const)
{
  return functor0(tp, fp);
}

#endif // #ifndef _FUNCTOR0_H_
 
//filename: functor0_rt.h
#ifndef _FUNCTOR0_RT_H_
#define _FUNCTOR0_RT_H_

template <typename R>
class functor0_rt
{
  class deleobject
  {
  };
  typedef R (*func_pt)();
  typedef R (deleobject::*mem_func_pt)();
  typedef R (deleobject::*cmem_func_pt)() const;
  functor_base<deleobject,
    func_pt, 
    mem_func_pt, 
    cmem_func_pt> base;
  
  public: 
    functor0_rt() : base() {}
    functor0_rt(func_pt pf) : base(pf) {}
    template<typename T> 
      functor0_rt(const T *pObject, R (T::*fp)()) :
        base((const deleobject*)(pObject), 
          *((mem_func_pt*)(&fp))) {}
    template<typename T> 
      functor0_rt(const T &pObject, R (T::*fp)()) :
        base((const deleobject*)(pObject), 
          *((mem_func_pt*)(&fp))) {}
    template<typename T> 
      functor0_rt(const T *pObject, R (T::*fp)() const) :
        base((const deleobject*)(pObject), 
          *((cmem_func_pt*)(&fp))) {}
    template<typename T> 
      functor0_rt(const T &pObject, R (T::*fp)() const) :
        base((const deleobject*)(pObject), 
          *((cmem_func_pt*)(&fp))) {}
  bool operator !=(const functor0_rt& rhs) const { return !(*this == rhs); }
  bool operator ==(const functor0_rt& rhs) const
  {
    return base == rhs.base;
  }
  bool operator ==(const void* rhs) const
  {
    return base == rhs;
  }
  functor0_rt& operator =(const functor0_rt& rhs)
  {
    base = rhs.base;
    return *this;
  }
  R operator()() const
  {
    if (base.m_pObject == NULL)
      return (*base.m_pf)();
    else
      return (base.m_pObject->*(base.m_pmf))();
  }
};

template <typename R>
inline functor0_rt<R> make_functor_rt(R (*fp)())
{
  return functor0_rt<R>(fp);
}

template <typename R, class T>
inline functor0_rt<R> make_functor_rt(const T* tp, R (T::*fp)())
{
  return functor0_rt<R>(tp, fp);
}

template <typename R, class T>
inline functor0_rt<R> make_functor_rt(const T* tp, R (T::*fp)() const)
{
  return functor0_rt<R>(tp, fp);
}

#endif // #ifndef _FUNCTOR0_RT_H_
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
<p> <span style="font-size:14px;color:#337FE5;">【为什么学爬虫?】</span> </p> <p> <span style="font-size:14px;">       1、爬虫入手容易,但是深入较难,如何写出高效率爬虫,如何写出灵活性高可扩展爬虫都是一项技术活。另外在爬虫过程,经常容易遇到被反爬虫,比如字体反爬、IP识别、验证码等,如何层层攻克难点拿到想要数据,这门课程,你都能学到!</span> </p> <p> <span style="font-size:14px;">       2、如果是作为一个其他行业开发者,比如app开发,web开发,学习爬虫能让你加强对技术认知,能够开发出更加安全软件和网站</span> </p> <p> <br /> </p> <span style="font-size:14px;color:#337FE5;">【课程设计】</span> <p class="ql-long-10663260"> <span> </span> </p> <p class="ql-long-26664262" style="font-size:11pt;color:#494949;"> 一个完整爬虫程序,无论大小,总体来说可以分成三个步骤,分别是: </p> <ol> <li class="" style="font-size:11pt;color:#494949;"> 网络请求:模拟浏览器行为从网上抓取数据。 </li> <li class="" style="font-size:11pt;color:#494949;"> 数据解析:将请求下来数据进行过滤,提取我们想要数据。 </li> <li class="" style="font-size:11pt;color:#494949;"> 数据存储:将提取到数据存储到硬盘或者内存。比如mysql数据库或者redis等。 </li> </ol> <p class="ql-long-26664262" style="font-size:11pt;color:#494949;"> 那么本课程也是按照这几个步骤循序渐进进行讲解,带领学生完整掌握每个步骤技术。另外,因为爬虫多样性,在爬取过程可能会发生被反爬、效率低下等。因此我们又增加了两个章节来提高爬虫程序灵活性,分别是: </p> <ol> <li class="" style="font-size:11pt;color:#494949;"> 爬虫进阶:包括IP代理,多线程爬虫,图形验证码识别、JS加密解密、动态网页爬虫、字体反爬识别等。 </li> <li class="" style="font-size:11pt;color:#494949;"> Scrapy和分布式爬虫:Scrapy框架、Scrapy-redis组件、分布式爬虫等。 </li> </ol> <p class="ql-long-26664262" style="font-size:11pt;color:#494949;"> 通过爬虫进阶知识点我们能应付大量反爬网站,而Scrapy框架作为一个专业爬虫框架,使他可以快速提高我们编写爬虫程序效率和速度。另外如果一台机器不能满足你需求,我们可以分布式爬虫让多台机器帮助你快速爬取数据。 </p> <p style="font-size:11pt;color:#494949;">   </p> <p class="ql-long-26664262" style="font-size:11pt;color:#494949;"> 从基础爬虫到商业化应爬虫,本套课程满足您所有需求! </p> <p class="ql-long-26664262" style="font-size:11pt;color:#494949;"> <br /> </p> <p> <br /> </p> <p> <span style="font-size:14px;background-color:#FFFFFF;color:#337FE5;">【课程服务】</span> </p> <p> <span style="font-size:14px;">专属付费社群+定期答疑</span> </p> <p> <br /> </p> <p class="ql-long-24357476"> <span style="font-size:16px;"><br /> </span> </p> <p> <br /> </p> <p class="ql-long-24357476"> <span style="font-size:16px;"></span> </p>
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值