Я работаю над проектом, в котором я получаю сообщение через UDP, и на основе этого сообщения я испускаю разные сигналы, и все они имеют одинаковые параметры.
Структура такая:
if (command_type == COMMAND_TYPE_MOVE)
{
emit sigMoveForward(data);
}
else if (command_type == COMMAND_TYPE_STOP)
{
emit sigStopMove(data);
}
Это становится очень утомительным для программирования и обслуживания, когда вы проходите около 10 команд. Есть ли способ сделать это лучше?
Я подумал о создании QMap, поиске по нему и передаче сигнала, который я получаю. Возможно ли в Qt иметь указатель на функцию и опускать его таким образом?





Если все сигналы содержат одинаковые data, вы можете отправить уникальный сигнал, содержащий 2 параметра (command_type + data), а затем проверить command_type в принимающем слоте.
//...
emit sigCommand(command_type, data)
//...
void MyClass::commandReceived(CommandType command_type, QVariant data) {
if (command_type == COMMAND_TYPE_MOVE)
{
moveForward(data);
}
else if (command_type == COMMAND_TYPE_STOP)
{
stopMove(data);
}
//...
}
Дело не в том, где я сравниваю, а в том, чтобы сократить количество сравнений, которые я должен написать. Также сигналы могут иметь разные связи с разными объектами.
@Curunir Но тогда, если у вас есть 15 разных команд, вам все равно нужно объявить 15 разных сигналов в своем заголовке, верно? Я не уверен, что поиск указателя функции в QMap будет намного эффективнее, чем, например, проверка command_type в переключателе и соответствующая подача правильного сигнала (как вы делаете сейчас).
Это не решение, вы перекладываете проблему с отправителя на получателя.
Нет никакой разницы между
emit sigMoveForward(data);
а также
sigMoveForward(data);
Таким образом, вы можете создать QMap с указателями на сигналы или лучше использовать простой массив, если команды непрерывны. Однако у него довольно сложный синтаксис.
void (Your_class::*signals[COMMAND_COUNT])(your_data_type) ;
...
signals[COMMAND_TYPE_MOVE] = &Your_class::moveForward;
signals[COMMAND_TYPE_STOP] = &Your_class::stopMove;
....
И излучать так:
(this->*signals[command_type])(data);
Это было именно то, что я искал, большое спасибо
Может быть, это шаблон команды, который вы ищете? Если вам разрешено не использовать только int или строку для команды, а инкапсулировать их в класс. Сигналы — это просто функции, поэтому вы можете хранить на них указатель.