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

以下是测试结果输出:

以下省略一万字。。。。

 

转载于:https://www.cnblogs.com/lxzCode/p/3731139.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++ 并没有原生的委托机制,但可以通过函数指针和对象指针来模拟委托机制。 在 C++ 中,函数指针可以作为参数传递和返回值,可以使用函数指针来实现委托的功能。而对象指针可以用于保存对象的状态和数据,也可以用于调用对象的成员函数。 以下是一个简单的 C++ 示例代码,演示了如何通过函数指针和对象指针来实现委托机制: ```cpp #include <iostream> #include <functional> using namespace std; class Delegate { public: void (*func)(void*); // 函数指针 void* obj; // 对象指针 void Invoke() { func(obj); // 调用函数指针 } }; class Test { public: void Print() { cout << "Hello, world!" << endl; } }; void PrintTest(void* obj) { Test* test = (Test*)obj; // 将对象指针转换为 Test 类型指针 test->Print(); // 调用对象的成员函数 } int main() { Test test; Delegate delegate; delegate.func = PrintTest; delegate.obj = &test; delegate.Invoke(); // 调用委托 return 0; } ``` 在这个示例代码中,我们定义了一个 `Delegate` 类,其中包含了一个函数指针和一个对象指针。`Invoke` 函数用于调用委托。我们还定义了一个 `Test` 类,其中包含了一个成员函数 `Print`。在 `main` 函数中,我们创建了一个 `Test` 对象 `test`,并创建了一个 `Delegate` 对象 `delegate`,将 `PrintTest` 函数的地址和 `test` 对象的地址分别赋值给 `Delegate` 对象的函数指针和对象指针。最后,我们通过 `delegate.Invoke()` 调用委托,实际上就是调用了 `PrintTest` 函数,并将 `test` 对象传递给了该函数,从而调用了 `Test` 对象的 `Print` 成员函数。 需要注意的是,这只是一个简单的示例,实际的委托机制可能更加复杂,并且需要考虑线程安全等问题。如果需要使用委托机制,建议使用现有的 C++ 第三方库或框架,如 Boost、Qt 等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值