熟悉C#的人都清楚delegate,也清楚委托的作用。
实现观察者模式,在C++中的一种做法就是通过接口继承来实现,这无疑大大增加了耦合度。通过delegate变可以解除这种耦合。
下面是上班时间,偷偷实现的一个我的delegate。直接上码:
#include<list> #include<functional> #include<iostream> #include<string> #include<algorithm> using namespace std; #ifdef _DEBUG #define OUTPUT(info) cout<<info <<endl<<endl; #else #define OUTPUT(info) #endif namespace lixz { template<class C,typename R,typename ...Args> class _delegate_class_mem { public: typedef R(C::*class_func_type)(Args...); _delegate_class_mem(class_func_type fun, C* class_ptr) :_fun(fun), _class_ptr(class_ptr) {} R operator()(Args&&...args) { return (_class_ptr->*_fun)(args...); } bool operator== (const _delegate_class_mem<C, R, Args...>&other) const { if (_class_ptr == other._class_ptr && _fun == other._fun) return true; return false; } template<typename T> bool operator==(const T&&)const { return false; } private: C* _class_ptr; class_func_type _fun; }; template<typename ...T> class delegate{ }; template<typename R, typename ...Args> class delegate<R(Args...)> { public: typedef std::function<R(Args...)> dele_func; typedef std::list<dele_func> function_list; typedef R(*func_type)(Args...); typedef delegate<R(Args...)> this_type; delegate() { OUTPUT("function type:"<< typeid(R(Args...)).name()) OUTPUT("args count:" << sizeof...(Args)) }; ~delegate() { func_list.clear(); } this_type& operator -=(func_type fun) { auto itr = std::find_if(func_list.begin(), func_list.end(), [&](dele_func&f)->bool { auto _fun = f.target<R(*)(Args...)>(); if (_fun && *_fun == fun) { return true; } return false; }); if (itr != func_list.end()) func_list.erase(itr); return *this; } template<class C> this_type& operator -=(_delegate_class_mem<C, R, Args...>&& class_mem_h) { auto itr = std::find_if(func_list.begin(), func_list.end(), [&](dele_func&f)->bool { auto _fun = f.target<_delegate_class_mem<C, R, Args...>>(); if (_fun && *_fun == class_mem_h) { return true; } return false; }); if (itr != func_list.end()) { func_list.erase(itr); } return *this; } this_type& operator +=(func_type fun) { func_list.push_back(fun); return *this; } template<class C> this_type& operator +=(_delegate_class_mem<C, R, Args...>&& class_mem_h) { func_list.push_back(class_mem_h); return *this; } void operator()(Args&&...args) { for (auto itr = func_list.begin(); itr != func_list.end(); itr++) { try { (*itr)(args...); } catch (exception ex) { //do something... } } } private: function_list func_list; }; template<typename C,typename R, typename ...Args> auto makeDelegateClassHelper(R(C::*class_func_type)(Args...), C* class_ptr) ->_delegate_class_mem<C, R, Args...> { return _delegate_class_mem<C, R, Args...>(class_func_type, class_ptr); } };
以下是测试用例:
void testFun1(string str) { cout << "testFun1=======:" << str << endl; } void testFun2(string str) { cout << "testFun2=======:" << str << endl; } class testfunClass1 { public: void testFun(string str) { cout << "testfunClass1::testFun=======:" << str << endl; } }; class testfunClass2 { public: void testFun(string str) { cout << "testfunClass2::testFun=======:" << str << endl; } }; using namespace lixz; int main(int argc, char**) { testfunClass1 tsc1; testfunClass2 tsc2; delegate<void(string)> f; f += testFun1; f += testFun2; f += makeDelegateClassHelper(&testfunClass1::testFun, &tsc1); f( string("delegate test string!")); OUTPUT(".............................................") f -= testFun1; f(string("delegate test string2!")); OUTPUT(".............................................") f -= testFun2; f += testFun1; f -= makeDelegateClassHelper(&testfunClass1::testFun, &tsc1); f(string("delegate test string3!")); OUTPUT(".............................................") f += makeDelegateClassHelper(&testfunClass2::testFun, &tsc2); f(string("delegate test string4!")); return 0; }
以下是测试结果输出:
以下省略一万字。。。。