CSDN博客

img coolcch

用 C++ 实现 C# 中的 委托/事件 (2-delegate event functor)

发表于2004/3/21 17:39:00  730人阅读

前两天看程序员杂志
看到关于 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: delegate.h
#ifndef _DELEGATE_H_
#define _DELEGATE_H_

#include <vector>
#include <algorithm>
#include "delegate_rt.h"

template <typename T>
class delegate
{
protected:
  std::vector<T> funcs;
public:
  typedef T FunctorType;

  delegate() {}
  explicit delegate(T Func)
  {
    if (!(Func == NULL)) funcs.push_back(Func);
  }
  delegate(const delegate& rhs) : funcs(rhs.funcs) {}

  void operator ()() const
  {
    typename std::vector<T>::const_iterator i = funcs.begin();
    for (; i != funcs.end(); ++i)
    {
      (*i)();
    }
  }
 template <typename P1>
  void operator ()(P1 p1) const
  {
    typename std::vector<T>::const_iterator i = funcs.begin();
    for (; i != funcs.end(); ++i)
    {
      (*i)(p1);
    }
  }
 template <typename P1, typename P2>
  void operator ()(P1 p1, P2 p2) const
  {
    typename std::vector<T>::const_iterator i = funcs.begin();
    for (; i != funcs.end(); ++i)
    {
      (*i)(p1, p2);
    }
  }
  bool operator ==(const delegate& rhs) const
  {
    return funcs == rhs.funcs;
  }
  bool operator ==(const void* rhs) const
  {
    if (funcs.size())
      return &funcs == rhs;
    return NULL == rhs;
  }

  delegate& operator =(const delegate& rhs)
  {
    funcs = rhs.funcs;
    return *this;
  }
  delegate& operator +=(const delegate& rhs)
  {
    if (this == &rhs)
      return *this;
    typename std::vector<T>::const_iterator j, i = rhs.funcs.begin();
    for (; i != rhs.funcs.end(); ++i)
    {
      j = std::find(funcs.begin(), funcs.end(), *i);
      if (j == funcs.end())
        funcs.push_back(*i);
    }
    return *this;
  }
  delegate& operator -=(const delegate& rhs)
  {
    if (this == &rhs)
    {
      funcs.clear();
      return *this;
    }
    typename std::vector<T>::iterator j;
    typename std::vector<T>::const_iterator i = rhs.funcs.begin();
    for (; i != rhs.funcs.end(); ++i)
    {
      j = std::find(funcs.begin(), funcs.end(), *i);
      if (j != funcs.end())
        funcs.erase(j);
    }
    return *this;
  }
  delegate operator +(const delegate& rhs) const
  {
    return delegate(*this) += rhs;
  }
  delegate operator -(const delegate& rhs) const
  {
    return delegate(*this) -= rhs;
  }

  delegate& operator =(T rhs)
  {
    funcs.clear();
    if (!(rhs == NULL))
      funcs.push_back(rhs);
    return *this;
  }
  delegate& operator +=(T rhs)
  {
    if (rhs == NULL)
      return *this;
    typename std::vector<T>::const_iterator j = 
      std::find(funcs.begin(), funcs.end(), rhs);
    if (j == funcs.end())
      funcs.push_back(rhs);
    return *this;
  }
  delegate& operator -=(T rhs)
  {
    if (rhs == NULL)
      return *this;
    typename std::vector<T>::iterator j = 
      std::find(funcs.begin(), funcs.end(), rhs);
    if (j != funcs.end())
      funcs.erase(j);
    return *this;
  }
  delegate operator +(T rhs) const
  {
    return delegate(*this) += rhs;
  }
  delegate operator -(T rhs) const
  {
    return delegate(*this) -= rhs;
  }
  friend delegate operator +(T lhs, const delegate& rhs)
  {
    return rhs + lhs;
  }
};

#endif // #ifndef _DELEGATE_H_
//filename: delegate_rt.h
#ifndef _DELEGATE_RT_H_
#define _DELEGATE_RT_H_

#include <vector>
#include <algorithm>
#include <stdexcept>

template <typename R, typename T>
class delegate_rt
{
protected:
  std::vector<T> funcs;
public:
  typedef T FunctorType;
  typedef R ReturnType;

  delegate_rt() {}
  explicit delegate_rt(T Func)
  {
    if (!(Func == NULL)) funcs.push_back(Func);
  }
  delegate_rt(const delegate_rt& rhs) : funcs(rhs.funcs) {}

  ReturnType operator ()() const
  {
    if (funcs.size() != 1)
      throw std::runtime_error("non-multicast delegate: method error!");
    return funcs.front()();
  }
 template <typename P1>
  ReturnType operator ()(P1 p1) const
  {
    if (funcs.size() != 1)
      throw std::runtime_error("non-multicast delegate: method error!");
    return funcs.front()(p1);
  }
 template <typename P1, typename P2>
  ReturnType operator ()(P1 p1, P2 p2) const
  {
    if (funcs.size() != 1)
      throw std::runtime_error("non-multicast delegate: method error!");
    return funcs.front()(p1, p2);
  }
  bool operator ==(const delegate_rt& rhs) const
  {
    return funcs == rhs.funcs;
  }
  bool operator ==(const void* rhs) const
  {
    if (funcs.size())
      return &funcs == rhs;
    return NULL == rhs;
  }

  delegate_rt& operator =(const delegate_rt& rhs)
  {
    funcs = rhs.funcs;
    return *this;
  }
  delegate_rt& operator +=(const delegate_rt& rhs)
  {
    if (this == &rhs)
      return *this;
    typename std::vector<T>::const_iterator j, i = rhs.funcs.begin();
    for (; i != rhs.funcs.end(); ++i)
    {
      j = std::find(funcs.begin(), funcs.end(), *i);
      if (j == funcs.end())
        funcs.push_back(*i);
    }
    return *this;
  }
  delegate_rt& operator -=(const delegate_rt& rhs)
  {
    if (this == &rhs)
    {
      funcs.clear();
      return *this;
    }
    typename std::vector<T>::iterator j;
    typename std::vector<T>::const_iterator i = rhs.funcs.begin();
    for (; i != rhs.funcs.end(); ++i)
    {
      j = std::find(funcs.begin(), funcs.end(), *i);
      if (j != funcs.end())
        funcs.erase(j);
    }
    return *this;
  }
  delegate_rt operator +(const delegate_rt& rhs) const
  {
    return delegate_rt(*this) += rhs;
  }
  delegate_rt operator -(const delegate_rt& rhs) const
  {
    return delegate_rt(*this) -= rhs;
  }

  delegate_rt& operator =(T rhs)
  {
    funcs.clear();
    if (!(rhs == NULL))
      funcs.push_back(rhs);
    return *this;
  }
  delegate_rt& operator +=(T rhs)
  {
    if (rhs == NULL)
      return *this;
    typename std::vector<T>::const_iterator j = 
      std::find(funcs.begin(), funcs.end(), rhs);
    if (j == funcs.end())
      funcs.push_back(rhs);
    return *this;
  }
  delegate_rt& operator -=(T rhs)
  {
    if (rhs == NULL)
      return *this;
    typename std::vector<T>::iterator j = 
      std::find(funcs.begin(), funcs.end(), rhs);
    if (j != funcs.end())
      funcs.erase(j);
    return *this;
  }
  delegate_rt operator +(T rhs) const
  {
    return delegate_rt(*this) += rhs;
  }
  delegate_rt operator -(T rhs) const
  {
    return delegate_rt(*this) -= rhs;
  }
  friend delegate_rt operator +(T lhs, const delegate_rt& rhs)
  {
    return rhs + lhs;
  }
};

#endif // #ifndef _DELEGATE_RT_H_
 
 
//filename: event.h
#ifndef _EVENT_H_
#define _EVENT_H_

typedef void* object;

class EventArgs
{
public:
  bool cancel;
  EventArgs() : cancel(false) {}
};

template <typename T>
class event
{
  T handlers;
public:
  void operator +=(const T& rhs)
  {
    handlers += rhs;
  }
  void operator -=(const T& rhs)
  {
    handlers -= rhs;
  }
  void operator()() const
  {
    handlers(NULL, EventArgs());
  }
   template <typename P1>
  void operator()(P1 p1) const
  {
    handlers(p1, EventArgs());
  }
   template <typename P1, typename P2>
  void operator()(P1 p1, P2 p2) const
  {
    handlers(p1, p2);
  }
};

#endif // #ifndef _EVENT_H_
 
//filename: functor.h
#ifndef _FUNCTOR_H_
#define _FUNCTOR_H_

template<typename T, typename T1, typename T2, typename T3>
class functor_base
{
public:
  typedef T deleobject;
  typedef T1 func_pt;
  typedef T2 mem_func_pt;
  typedef T3 cmem_func_pt;
  union
  {
    func_pt m_pf;
    mem_func_pt m_pmf;
    cmem_func_pt m_pcmf;
  };
  union
  {
    deleobject *m_pObject;
    const deleobject *m_pcObject;
  };
  functor_base() : m_pf(NULL), m_pObject(NULL) {}
  functor_base(func_pt pf) : 
    m_pf(pf), m_pObject(NULL) {}
  functor_base(const deleobject *pObject, mem_func_pt pf) : 
    m_pmf(pf), m_pcObject(pObject) {}
  functor_base(const deleobject *pObject, cmem_func_pt pf) : 
    m_pcmf(pf), m_pcObject(pObject) {}
  bool operator !=(const functor_base& rhs) const { return !(*this == rhs); }
  bool operator ==(const functor_base& rhs) const
  {
    if (m_pObject == NULL)
      return rhs.m_pObject == NULL && m_pf == rhs.m_pf;
    return m_pObject == rhs.m_pObject && m_pmf == rhs.m_pmf;
  }
  bool operator ==(const void* rhs) const
  {
    return m_pObject == NULL ? m_pf == rhs : *(const void**)&m_pmf == rhs;
  }
  functor_base& operator =(const functor_base& rhs)
  {
    if (&rhs == this)
      return *this;
    m_pObject = rhs.m_pObject;
    if (m_pObject == NULL)
      m_pf = rhs.m_pf;
    else
      m_pmf = rhs.m_pmf;
    return *this;
  }
};

#include "functor0.h"
#include "functor1.h"
#include "functor2.h"
#include "functor0_rt.h"
#include "functor1_rt.h"
#include "functor2_rt.h"

#endif // #ifndef _FUNCTOR_H_
0 0

相关博文

我的热门文章

img
取 消
img