gpt4 book ai didi

c++ - 是否可以使用包含 {sub,super} 类函数指针的回调表?

转载 作者:行者123 更新时间:2023-11-28 04:17:26 25 4
gpt4 key购买 nike

我目前有一个连接对象,它对传入的命令请求执行处理。每个命令都是一个字符串,使用无序映射映射到回调方法。一个说明核心功能的精简示例:

#include <iostream>
#include <string>
#include <unordered_map>
#include <functional>

class Conn;
typedef void (Conn::*ProcFn)();

class Conn
{
private:
void proc_ping();

static const std::unordered_map<std::string, ProcFn> handlers;

public:
void simulate();
};

const std::unordered_map<std::string, ProcFn> Conn::handlers = {
std::pair("ping", &Conn::proc_ping)
};

void Conn::proc_ping()
{
std::cout << "ping!" << std::endl;
}

void Conn::simulate()
{
auto pfn = handlers.at("ping");

std::invoke(pfn, this);
}

int main()
{
Conn c;

c.simulate();
}

这工作正常,但我意识到我需要多个不同的网络接口(interface),它们具有不同的主要角色(想想“管理接口(interface)”与“客户端数据接口(interface)”)所以我将 Conn 类复制到 ConnMgmt 和 ConnData .但是,很快就会发现处理程序之间存在足够多的重叠,因此有必要为两者创建一个通用类。

我想做的是创建一个包含 ConnMgmt 和 ConnData 共享功能的 ConnBase。

我的问题与回调函数表有关。

我想要一个单独的表来将命令请求字符串映射到回调函数,但是我希望方法指针能够引用派生类中的方法。 IE。我有一个用于 ConnBase 和 ConnMgmt 或 ConnBase 和 ConnData 的调度程序(取决于调用哪个接口(interface))。

这是[非功能性]代码,说明了我想要完成的要点:

#include <iostream>
#include <string>
#include <unordered_map>
#include <functional>

class ConnBase;
typedef void (ConnBase::*ProcFn)();

class ConnBase
{
protected:
void proc_ping();
};

void ConnBase::proc_ping()
{
std::cout << "ping!" << std::endl;
}

class ConnMgmt : public ConnBase
{
protected:
static const std::unordered_map<std::string, ProcFn> handlers;

void proc_create_user();

public:
void simulate();
};

void ConnMgmt::proc_create_user()
{
std::cout << "create user!" << std::endl;
}

const std::unordered_map<std::string, ProcFn> ConnMgmt::handlers = {
std::pair("ping", &ConnBase::proc_ping),
std::pair("create_user", &ConnMgmt::proc_create_user)
};

void ConnMgmt::simulate()
{
auto pfn = handlers.at("ping");

std::invoke(pfn, this);

pfn = handlers.at("create_user");

std::invoke(pfn, this);
}

int main()
{
ConnMgmt c;

c.simulate();
}

这段代码在几个方面被破坏了,但我特别想知道是否:

  • 拥有一个包含指向 ConnBase 和 ConnMgmt 中的方法指针的“ConnMgmt::handlers”表的想法是否从根本上被打破了?编译器发出声音,说指针类型错误。
  • 如果有一种方法可以解决问题,我会进入未定义行为(或更糟)的领域吗?我读过它“应该”可以为子类使用方法指针类型,但是有一些与虚类相关的警告(并且注意:类中有 are 虚函数,但是所有处理函数都不是虚拟的)。
  • 考虑到我想要完成的事情(创建一个字符串到方法的调度程序,其中的方法可能驻留在不同的类中(尽管总是属于同一类层次结构)),是否有一些惯用的 C++17 方法可以做到这一点?

(不允许提升)。

最佳答案

您可以通过一些更改来完成您需要的操作。

如果将 ProcFn 的类型更改为

typedef void (ConnMgmt::*ProcFn)();

然后您就差不多准备好构建您的ConnMgmt::handlers 表了。您需要为 std::pair 指定类型。那么剩下的问题就是 ConnBase::proc_ping 受到保护,无法访问。解决这个问题的方法是将引用更改为 ConnMgmt::proc_ping

const std::unordered_map ConnMgmt::handlers = { std::pair("ping", &ConnMgmt::proc_ping), std::pair("create_user", &ConnMgmt::proc_create_user)};

每个派生类都需要自己的处理程序表和 ProcFn 类型定义。

关于c++ - 是否可以使用包含 {sub,super} 类函数指针的回调表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56305090/

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