多播委托,[C++]给C++封装一个多播委托

一来闲的蛋疼,二来我们代码里面有一些fastdelegate的代码,在clang下面实在编译不过去,所以打算重造一个轮子,至少标准一点(换个编译器能编译过去...)....
废话不说,上代码:
// C++版的多播委托,使用boost::function // 为了在各个编译器下面都能编译 // author:egmkang #ifndef __ZEVENT_T_H__ #define __ZEVENT_T_H__ #include #include template class zEventBaseT { public: typedef T DelegateType; typedef std::list ContainerType; typedef typename ContainerType::iterator IterType; inline void add(DelegateType *p) { if(p && !contains(p)) { _impl_list.push_back(p); } } inline void remove(DelegateType *p) { _impl_list.remove(p); } inline void operator +=(DelegateType *p) { add(p); } inline void operator -=(DelegateType *p) { remove(p); } protected: zEventBaseT(){} virtual ~zEventBaseT() { _impl_list.clear(); } inline bool contains(DelegateType *p) { for(IterType iter = _impl_list.begin(); iter != _impl_list.end(); ++iter) { if(*iter == p) return true; } return false; } protected: ContainerType _impl_list; }; template class zEventT; #define EVENT_CALL(...) \ { \ ContainerType& impl = this->_impl_list; \ for(IterType iter = impl.begin(); \ iter != impl.end(); \ ++iter) \ { \ (*(*iter))(__VA_ARGS__); \ } \ } //FUNCTION_ARGS = 0 template<> class zEventT >: public zEventBaseT > { public: void operator()() { EVENT_CALL(); } }; //FUNCTION_ARGS = 1 template class zEventT >: public zEventBaseT > { public: typedef typename zEventBaseT >::ContainerType ContainerType; typedef typename zEventBaseT >::IterType IterType; void operator()(P1 p1) { EVENT_CALL(p1); } }; //FUNCTION_ARGS = 2 template class zEventT >: public zEventBaseT > { public: typedef typename zEventBaseT >::ContainerType ContainerType; typedef typename zEventBaseT >::IterType IterType; void operator()(P1 p1,P2 p2) { EVENT_CALL(p1,p2); } }; //FUNCTION_ARGS = 3 template class zEventT >: public zEventBaseT > { public: typedef typename zEventBaseT >::ContainerType ContainerType; typedef typename zEventBaseT >::IterType IterType; void operator()(P1 p1,P2 p2,P3 p3) { EVENT_CALL(p1,p2,p3); } }; //FUNCTION_ARGS = 4 template class zEventT >: public zEventBaseT > { public: typedef typename zEventBaseT >::ContainerType ContainerType; typedef typename zEventBaseT >::IterType IterType; void operator()(P1 p1,P2 p2,P3 p3,P4 p4) { EVENT_CALL(p1,p2,p3,p4); } }; #endif//__ZEVENT_T_H__
这里最多支持函数有四个参数,如果想要支持多的话,自己添上去就行.
使用该类的代码:
#include "zEvent.hpp" #include #include #include void printA(int a,int b) { std::cout << (a+b) << std::endl; } void printB(int a,int b) { std::cout << (a + b) << std::endl; } int main() { typedef zEventT > PrintEvent; typedef PrintEvent::DelegateType DelegateType; PrintEvent _event; DelegateType delegate1 = boost::bind(&printA,10,_1); DelegateType delegate2 = boost::bind(&printB,12,_1); _event += &delegate1; _event += &delegate2; _event(18); std::cout << std::endl; _event -= &delegate1; _event(19); system("pause"); return 0; }

之所以委托链内存的是指针,原因有2:
1. 指针很容易比较
2. boost::function比较貌似有一点问题
用boost::function有一点好处,就是可以通过boost::bind完成一些复杂的功能:-),而且boost::function也是C++0x的内容之一
PS:
随手写了一个,至少兼容VC,GCC 4.4+,clang 2.8,有什么问题或者建议都可以留言,欢迎斧正.
clang真是一个好东西啊,准备把我们服务器的代码改的在clang下面可以编译过去,用clang做代码分析检查:-D
我自己对容器内存的顺序没要求,所以把容器换成set了哈,哈哈
Tags:  多播组播 多播地址 多播委托

延伸阅读

最新评论

发表评论