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