C++仿c#的delegate的实现源码

最近写了一个把回调函数和回调对象成员函数统一的类,并实现了一个仿c#的delegate,仅供参考,有兴趣改进的请回复并附源码,一起进步,谢谢。

类之间的继承关系见下图:
这里写图片描述

下面附源码和测试程序
Delegate.hpp

/*
 * Delegate.hpp
 *
 *  Created on: Aug 31, 2016
 *      Author: root
 */

#ifndef DELEGATE_HPP_
#define DELEGATE_HPP_

#include <vector>

template <typename... Types>
class CallBackBase
{
public:
    CallBackBase() {}
    virtual ~CallBackBase() {};
    virtual void operator () (Types... args) = 0;
};

template <typename... Types>
class CallBackFunction : public CallBackBase<Types...>
{
public:
    typedef void (*FPCallBack)(Types... args);

    CallBackFunction(){}

    CallBackFunction(FPCallBack pFunc)
    {
        if (pFunc != nullptr)
        {
            m_fpCallBack = pFunc;
        }
    }

    virtual ~CallBackFunction()
    {
    }

    virtual void operator () (Types... args)
    {
        if (m_fpCallBack != nullptr)
            m_fpCallBack(args...);
        //throw std::exception("null function address is called");
        return ;
    }

private:
    FPCallBack m_fpCallBack = nullptr;
};

template <typename T, typename... Types>
class CallBackMethod : public CallBackBase<Types...>
{
public:
    typedef void (T::*FPClassCallBack)(Types... args);

    CallBackMethod(){}

    CallBackMethod(T *pThis, FPClassCallBack pFunc)
    {
        if (pThis != nullptr && pFunc != nullptr)
        {
            m_pThis = pThis;
            m_fpCallBack = pFunc;
        }
    }

    virtual ~CallBackMethod()
    {
    }

    virtual void operator () (Types... args)
    {
        if (m_pThis != nullptr && m_fpCallBack != nullptr)
        {
            (m_pThis->*m_fpCallBack)(args...);
        }
        //throw std::exception("null function address is called");
        return ;
    }

private:
    T *m_pThis = nullptr;
    FPClassCallBack m_fpCallBack = nullptr;
};

template <typename... Types>
class Delegate
{
    using CallBackType = CallBackBase<Types...>;
public:
    Delegate(){};
    Delegate(CallBackType *callBack)
    {
        _vecCallBack.clear();
        _vecCallBack.push_back(callBack);
    }

    virtual ~Delegate() {};

    void operator () (Types... args)
    {
        for (auto item : _vecCallBack)
        {
            (*item)(args...);
        }
    }

    virtual void operator += (CallBackType *pFunc)
    {
        if (pFunc != nullptr)
        {
            _vecCallBack.push_back(pFunc);
        }
    }

    virtual void operator -= (CallBackType *pFunc)
    {
        if (pFunc != nullptr)
        {
            auto it = _vecCallBack.begin();
            for (; it != _vecCallBack.end(); ++it)
            {
                if (*it == pFunc)
                {
                    _vecCallBack.erase(it);
                    break;
                }
            }
            //auto it = std::find(_vecCallBack.rbegin(), _vecCallBack.rend(), pFunc);
            //if (it != _vecCallBack.cend())
            //  _vecCallBack.erase(it);
        }
    }

private:
    std::vector<CallBackType*> _vecCallBack;
};

#endif /* DELEGATE_HPP_ */

DelegateTest.cpp

//============================================================================
// Name        : DelegateTest.cpp
// Author      : Zhangjf
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
#include "Delegate.hpp"

using namespace std;

void print1(std::string strP);

class Test1
{
public:
    void print1(std::string str1)
    {
        printf("%s, %d: %s\n", __func__, __LINE__, str1.c_str());
        return ;
    }
};

int main() {

    CallBackFunction<std::string> callBack1(print1);
    Delegate<std::string> d1(&callBack1);
    d1("test1");

    Test1 t;
    CallBackMethod<Test1, std::string> callBack2(&t, &Test1::print1);
    d1 += &callBack2;

    d1("test2");

    d1 -= &callBack1;
    d1("test3");

    return 0;
}

void print1(std::string strP)
{
    printf("%s, %d, %s\n", __func__, __LINE__, strP.c_str());
    return ;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值