当有多个不同参数的回调函数需要管理时我们怎么办呢?它们并不能存放在同一个数组或者容器里面。
首先,我们可以定义一个抽象基类MyFunc,只有一个用来描述类型的成员变量type。然后从基类中派生出一个模板类SubFunc这样就可以存放不同的回调函数了。
由于这些存放回调函数的模板类都是从同一个基类派生,所以我们直接存放它们的父类就可以了,之后可以根据父类
中的类型dynamic_cast为相应的子类。
typedef std::tr1::function<int(const unsigned char*, unsigned int)> TestCallback;
class MyFunc
{
public:
int type;
virtual ~MyFunc() = 0 { }
};
template<typename Fty>
class SubFunc : public MyFunc
{
public:
SubFunc(int t, std::tr1::function<Fty> f)
{
type = t;
func = f;
}
std::tr1::function<Fty> func;
};
void test1(int i)
{
std::cout << "test1:" << i << std::endl;
}
void test2(const std::string &str)
{
std::cout << "test2:" << str << std::endl;
}
void test3(int i, const std::string &str)
{
std::cout << "test3:" << i << "," << str << std::endl;
}
typedef std::tr1::shared_ptr<MyFunc> MyFuncPtr;
std::map<int, MyFuncPtr> g_arr;
void Add1(std::tr1::function<void(int)> f)
{
MyFuncPtr ptr(new SubFunc<void(int)>(1, f));
g_arr.insert(std::pair<int, MyFuncPtr>(1111, ptr));
}
void Add2(std::tr1::function<void(const std::string&)> f)
{
MyFuncPtr ptr(new SubFunc<void(const std::string&)>(2, f));
g_arr.insert(std::pair<int, MyFuncPtr>(2222, ptr));
}
void Add3(std::tr1::function<void(int, const std::string&)> f)
{
MyFuncPtr ptr(new SubFunc<void(int, const std::string&)>(3, f));
g_arr.insert(std::pair<int, MyFuncPtr>(3333, ptr));
}
void HandleAllCallback(const unsigned char *response)
{
// 解析response
std::map<int, MyFuncPtr>::iterator iter = g_arr.find(3333);
if (iter!=g_arr.end())
{
MyFunc *p = iter->second.get();
switch (p->type)
{
case 1:
{
int i = 1111;
dynamic_cast<SubFunc<void(int)>*>(p)->func(i);
}
break;
case 2:
{
std::string str2 = "str2";
dynamic_cast<SubFunc<void(const std::string&)>*>(p)->func(str2);
}
break;
case 3:
{
std::string str3 = "str3";
dynamic_cast<SubFunc<void(int, const std::string&)>*>(p)->func(3333, str3);
}
break;
default:
break;
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
// 接口
Add1(std::tr1::bind(test1, std::tr1::placeholders::_1));
Add2(std::tr1::bind(test2, std::tr1::placeholders::_1));
Add3(std::tr1::bind(test3, std::tr1::placeholders::_1, std::tr1::placeholders::_2));
// OnMessage
unsigned char *response = NULL;
HandleAllCallback(response);
system("pause");
return 0;
}