您的位置:首页 > 编程语言 > C语言/C++

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

2016-11-25 11:29 281 查看
最近写了一个把回调函数和回调对象成员函数统一的类,并实现了一个仿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 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息