通过带有成员函数指针的 QHash 调用成员函数的正确方法

Posted

技术标签:

【中文标题】通过带有成员函数指针的 QHash 调用成员函数的正确方法【英文标题】:Correct way to call a member function via a QHash with member function pointers 【发布时间】:2019-08-12 18:13:23 【问题描述】:

我有一个服务器类,它处理QJsonObject 数据并根据数据中设置的键对其进行处理。

目前,我使用一个大的 if-then-else 语句来决定像这样做什么:

const QString action = jsonObject.value(KEY_ACTION).toString();
if (action == SOME_ACTION) 
    // do something
 else if (action == SOME_OTHER_ACTION) 
    // do something else

等等。现在,与此同时,我有很多操作,对于每一个操作,我的服务器都必须检查所有案例,直到找到正确的案例。因此,我想知道是否有更好的方法来做到这一点。

我考虑过在不同的函数中处理数据,并有一个 QHash 与相应的函数指针指向每个操作的相应函数,如下所示:

在构造函数中:

const QHash<QString, void(Server::*)(const QJsonObject &)> processFunctionsMap 
     SOME_ACTION, &Server::processSomeAction ,
     SOME_OTHER_ACTION, &Server::processSomeOtherAction 

以及各自的功能:

void Server::processSomeAction(const QJsonObject &data)

    ...

然后调用匹配函数:

if (! processFunctionsMap.contains(action)) 
    // Catch this case

(this->*processFunctionsMap.value(action))(jsonObject);

这似乎可行,但我不是 C++ 专业人士,所以我的问题是这是否是正确的方法。

【问题讨论】:

【参考方案1】:

您的方法是合理的,但您已将不匹配的情况从执行 else 块(可能什么都不做)更改为即时未定义的行为。

您需要将哈希查找与调用分开,以便您可以在两者之间插入成功查找的检查。使用 C++ 标准集合(std::map 是红黑树,std::unordered_map 是哈希表),这将是对返回迭代器的 find(key) 的调用......您将其与 map.end() 和如果它们相等,请确保不要取消引用。 QHash 或任何其他非标准哈希表肯定会提供类似的东西。

Understanding what QHash does when key not found

【讨论】:

感谢您确认这样做没问题 :-) 对不起,示例不完整,我将编辑我的代码以避免未定义的行为。

以上是关于通过带有成员函数指针的 QHash 调用成员函数的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

C++|详解类成员指针:数据成员指针和成员函数指针及应用场合

如何通过保存在容器中的成员指针函数调用?

c++类的成员函数指针如何转为普通指针

通过指针C++调用成员函数,对象为空?

通过VC++中的A类函数指针调用(B类的)类成员函数

this指针