C++ 带有额外数据的函数指针
我有一个处理包的类:C++ 带有额外数据的函数指针,c++,qt4,C++,Qt4,我有一个处理包的类: typedef void (*FCPackageHandlerFunction)(FCPackage*); class FCPackageHandlers{ ... void registerHandler(FCPackage::Type type, FCPackageHandlerFunction handler); void handle(FCPackage* package); ... QHash<FCPackage::T
typedef void (*FCPackageHandlerFunction)(FCPackage*);
class FCPackageHandlers{
...
void registerHandler(FCPackage::Type type, FCPackageHandlerFunction handler);
void handle(FCPackage* package);
...
QHash<FCPackage::Type, FCPackageHandlerFunction> _handlers;
};
有人知道正确的解决方案吗?您试图将函数对象存储在函数指针中,但这是不可能的。您应该存储一个
std::tr1::function
:
#include <functional>
typedef std::tr1::function<void(FCPackage*)> FCPackageHandlerFunction;
class FCPackageHandlers{
...
void registerHandler(FCPackage::Type type, FCPackageHandlerFunction handler);
void handle(FCPackage* package);
...
QHash<FCPackage::Type, FCPackageHandlerFunction> _handlers;
};
std::tr1::bind
在Boost中也可用,如果您没有访问权限,也可以始终使用std::bind2nd
编辑:由于无法修改FCPackageHandlerFunction
的类型,最好添加另一个散列来存储与每个函数指针关联的数据:
typedef void (*FCPackageHandlerFunction)(FCPackage*);
class FCPackageHandlers{
...
void registerHandler(FCPackage::Type type, FCPackageHandlerFunction handler,
FCServer * func_data);
void handle(FCPackage* package);
...
QHash<FCPackage::Type, FCPackageHandlerFunction> _handlers;
QHash<FCPackageHandlerFunction, FCServer*> _handler_func_data;
};
// The server will be passed by the package handler which will
// extract it from the _handler_func_data hash
void handle_FC_login(FCServer* server, FCPackage* package)
{
std::cout << "Received package: " << package->toString().data() << "\n";
}
FCServer::FCServer(){
_handlers.registerHandle(FCPackage::Login, &handle_FC_login, this );
}
问题是,我无法更改FCPackageHandler函数类型。还有其他解决办法吗?
#include <functional>
typedef std::tr1::function<void(FCPackage*)> FCPackageHandlerFunction;
class FCPackageHandlers{
...
void registerHandler(FCPackage::Type type, FCPackageHandlerFunction handler);
void handle(FCPackage* package);
...
QHash<FCPackage::Type, FCPackageHandlerFunction> _handlers;
};
void handle_FC_login(FCServer* server, FCPackage* package)
{
std::cout << "Received package: " << package->toString().data() << "\n";
// You can use server if you need it
}
FCServer::FCServer()
{
_handlers.registerHandle(FCPackage::Login,
std::tr1::bind(&handle_FC_login, this, _1));
}
typedef void (*FCPackageHandlerFunction)(FCPackage*);
class FCPackageHandlers{
...
void registerHandler(FCPackage::Type type, FCPackageHandlerFunction handler,
FCServer * func_data);
void handle(FCPackage* package);
...
QHash<FCPackage::Type, FCPackageHandlerFunction> _handlers;
QHash<FCPackageHandlerFunction, FCServer*> _handler_func_data;
};
// The server will be passed by the package handler which will
// extract it from the _handler_func_data hash
void handle_FC_login(FCServer* server, FCPackage* package)
{
std::cout << "Received package: " << package->toString().data() << "\n";
}
FCServer::FCServer(){
_handlers.registerHandle(FCPackage::Login, &handle_FC_login, this );
}
void FCPackageHandlers::handle(FCPackage * package)
{
// Query function
FCPackageHandlerFunction func = _handlers[package->GetType()];
// Query associated data
FCServer * server = _handler_func_data[func];
// Call handler
func(server, package);
}