最近写了一个把回调函数和回调对象成员函数统一的类,并实现了一个仿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 ;
}