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

原创 2004年03月21日 17:39:00

前两天看程序员杂志
看到关于 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_

C++ 使用事件(event)

C++ 使用事件(event)   // mcppv2_events.cpp // compile with: /clr using namespace System; // dec...
  • ooyyee
  • ooyyee
  • 2015年11月17日 09:41
  • 605

C++封装C#中的事件

背景:   用户要求我们提供给他们API,如果这些API都是用C#写的DLL,而用户要求API为C++的 DLL,这种情况下就需要将C# DLL里面的内容封装成C++ DLL。 这里针对c#中的事...
  • sudazf
  • sudazf
  • 2016年08月09日 11:40
  • 1887

最接近C# 的Event的C++处理

boost Event
  • BlueDog
  • BlueDog
  • 2011年02月15日 23:27
  • 3040

C#中的委托(Delegate)和事件(Event)

分类:   把C#中的委托(Delegate)和事件(Event)放到现在讲是有目的的:给下次写的设计模式——观察者(Observer)有一个参考。     委托和事件应该是C#相较于...
  • haihsl123456789
  • haihsl123456789
  • 2015年03月13日 22:45
  • 953

终于会用c#中的delegate(委托)和event(事件)了

一、开篇忏悔 对自己最拿手的编程语言C#,我想对你说声对不起,因为我到现在为止才明白c#中的delegate和event是怎么用的,惭愧那。好了,那今天就趁月黑风高的夜晚简单来谈谈delegate和...
  • Sayesan
  • Sayesan
  • 2016年03月03日 13:35
  • 503

C#控件的委托与事件浅析

先给一个实现事件的case: using System; //声明一个委托 public delegate void MyEventHandler(object sender, EventArgs e...
  • lelelaogu
  • lelelaogu
  • 2014年03月04日 17:11
  • 588

C# ~ 从 委托事件 到 观察者模式

委托和事件的部分基础知识可参见 C#/.NET 基础学习 之 [委托-事件] 部分 ;参考 [1]. 从无到有 谈委托、事件和观察者模式; [2]. 初识事件 到 自定义事件; [3]. 从类型...
  • qing101
  • qing101
  • 2016年08月15日 19:00
  • 1640

C#中的代理委托和event关键字

也叫作委托。事实上,代理就是用于定义指向方法的引用。 比如你在你眼前的程序中要调用另一部分程序的内容(方法或属性),但是,你不能保证函数名或者属性名不发生变化,或者根本程序不可见(不是public或...
  • define_us
  • define_us
  • 2016年06月16日 20:24
  • 601

C#的COM事件在C++中触发和响应的实现

在C++中调用C#开发COM组件时,一般的接口调用都比较容易实现,但是对于COM组件中的事件,C++中要去响应却不好实现。因为C#中事件是采用委托机制,而C++中却没有委托的机制,这样就无法实现对应。...
  • hu_jiangan
  • hu_jiangan
  • 2014年11月01日 20:50
  • 1390

C# 中的委托与事件

委托与事件是C#中的重要概念,这两个概念既有联系又有区别,容易混淆,下面就对C#中的这两个概念进行一下比较。 1.委托 声明委托的语法和声明函数非常类似,不过需要使用delegate关键字...
  • u014359097
  • u014359097
  • 2015年11月27日 10:39
  • 572
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:用 C++ 实现 C# 中的 委托/事件 (2-delegate event functor)
举报原因:
原因补充:

(最多只允许输入30个字)