zoukankan      html  css  js  c++  java
  • delegate委托的C++实现--C++11/14(原创)

    熟悉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;
    }
    
    

    以下是测试结果输出:

    以下省略一万字。。。。
  • 相关阅读:
    一卡通应用系统解决方案
    2013524 项目一
    射频RFID系统
    SIM操作系统
    python中eval, exec, execfile,和compile [转载]
    FastJSON学习
    坑爹的UICollectionView
    8位单片机编程的一些坑
    Android DownloadThread.run()学习
    蓝牙接收苹果手机通知 ANCS协议分析
  • 原文地址:https://www.cnblogs.com/lxzCode/p/3731139.html
Copyright © 2011-2022 走看看