gpt4 book ai didi

c++ - 带有额外数据的函数指针

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:00:59 25 4
gpt4 key购买 nike

我有处理包的类:

typedef void (*FCPackageHandlerFunction)(FCPackage*);
class FCPackageHandlers{
...
void registerHandler(FCPackage::Type type, FCPackageHandlerFunction handler);
void handle(FCPackage* package);
...
QHash<FCPackage::Type, FCPackageHandlerFunction> _handlers;
};

然后我有一个接收包的服务器类。现在我想注册一个处理包的函数。但是这个函数必须有一个用于其他变量的服务器实例。

所以我试试这个:

struct FCLoginHandler{
FCServer* server;

FCLoginHandler(FCServer* server){
this->server = server;
}

void operator()(FCPackage* package){
std::cout << "Received package: " << package->toString().data() << "\n";
}
};

...

FCServer::FCServer(){
_handlers.registerHandle(FCPackage::Login, FCLoginHandler(this));
}

但是我得到了这个错误:

error: no matching function for call to 'FCPackageHandlers::registerHandler(FCPackage::Type, FCLoginHandler)'
note: candidates are: void FCPackageHandlers::registerHandler(FCPackage::Type, void (*)(FCPackage*))

有人知道正确的解决方案吗?

最佳答案

您正试图将函数对象存储在函数指针中,这是不可能的。你应该存储一个 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;
};

Boost 中有一个类似的 function 类,以防您还没有访问 std::tr1 的权限。

另外,考虑使用 boost::bind 和一个常规函数来避免必须创建您自己的函数对象的样板,例如 FCLoginHandler:

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));
}

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 );
}

大概这就是您必须如何实现 FCPackageHandlers::handle:

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);
}

关于c++ - 带有额外数据的函数指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2229353/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com