В настоящее время я пишу программу, которая должна вызывать определенные функции в зависимости от байта ответа, отправленного последовательным устройством. Поскольку количество команд несколько велико (~ 140 команд), я решил, что более простой подход - связать байты ответа с соответствующими функциями «интерпретации» фрейма с помощью QMap, который создается следующим образом:
class ConfidentialDevice;
typedef void (ConfidentialDevice::*readerFunction_t)(const Frame &frame);
class ConfidentialDevice : public QObject {
// QObject stuff...
private:
// Frame interpretation functions
void readerFunctionA(const Frame& frame);
void readerFunctionB(const Frame& frame);
void readerFunctionc(const Frame& frame);
// And so on...
// God-function that calls the other functions depending on frame response byte
void readFrame(const Frame& frame);
// Registers all frame interpretation functions in the map
void registerInterpretationFunctions();
private:
// QMap that relates response byte to functions
QMap<quint8, readerFunction_t> m_functionMap;
};
Реализация registerInterpretationFunctions()
выглядит так:
void ConfidentialDevice::registerFrameInterpretationFunctions()
{
// Clear function map
m_functionMap.clear();
// Register response functions
m_functionMap.insert(SECRET_DEVICE_COMMAND_A,
&ConfidentialDevice::readerFunctionA);
m_functionMap.insert(SECRET_DEVICE_COMMAND_B,
&ConfidentialDevice::readerFunctionB);
m_functionMap.insert(SECRET_DEVICE_COMMAND_C,
&ConfidentialDevice::readerFunctionC);
// And so on...
}
До этого момента все работает и компилируется правильно. Однако у меня возникают проблемы, когда я хочу вызвать функцию, зарегистрированную в m_functionMap
. На данный момент у меня есть этот код в функции readFrame
:
void ConfidentialDevice::readFrame(const Frame &frame)
{
// Call apropiate frame interpretation function
if (m_functionMap.contains(frame.command()))
{
readerFunction_t fun = m_functionMap.value(frame.command()); // This works
(*fun)(frame); // <-- I want to call `fun`, but this results in a compilation error
}
}
Ошибка компилятора:
indirection requires pointer operand ('readerFunction_t' (aka 'void (ConfidentialDevice::*)(const Frame &)') invalid)
Есть ли способ обойти эту проблему? Можно использовать switch-case для всех команд, но в результате получается менее читаемый, менее обслуживаемый и более подверженный ошибкам код.
Заранее спасибо!
(this->*fun)(frame);
. См. Вызов методов класса C ++ с помощью указателя функции. - person dxiv   schedule 31.01.2021