Я пытаюсь реализовать шаблон двойной отправки для интерфейса сообщений на С++. Однако я обнаружил, что должен быть слишком подробным в своем классе обработчика из-за необходимости пересылать объявление каждого сообщения.
Я ищу способ структурировать файлы, чтобы иметь возможность опускать предварительные объявления.
Я знаю, что могу создать шаблон класса MessageHandler с кортежем всех доступных сообщений. Однако я нашел это недостаточно простым и искал более простые и объяснимые методы.
struct MessageA;
struct MessageB;
// etc...
class MessageHandler {
public:
virtual void handle(MessageA& m);
virtual void handle(MessageB& m);
// etc...
virtual void handle(Message&) {}
};
struct Message {
virtual void dispatch(MessageHandler&) = 0;
};
template<typename ActualMessage>
struct MessageHelper : Message {
void dispatch(MessageHandler& handler)
{
handler.handle(static_cast<ActualMessage&>(*this));
}
};
struct MessageA : MessageHelper<MessageA> {};
struct MessageB : MessageHelper<MessageB> {};
// etc...
В реальном коде я имею дело с более чем 20 сообщениями. Я согласен с многословием класса обработчика, предварительные объявления немного «много».
Могу ли я каким-то образом реструктурировать это? Конечно, я ограничен из-за того, что класс MessageHelper является шаблонным. Это ограничивает меня в прямом объявлении класса MessageHandler.
Спасибо!
🤔 А знаете ли вы, что...
Язык C++ имеет возможность работы с файлами и потоками данных.
Вы не можете полностью избавиться от предварительных объявлений, но вы можете изменить порядок так, чтобы вам нужно было только пересылать объявления MessageHandler
и ни одно из сообщений:
struct MessageHandler;
struct Message {
virtual void dispatch(MessageHandler&) = 0;
};
template<typename ActualMessage>
struct MessageHelper : Message {
void dispatch(MessageHandler& handler);
};
struct MessageA : MessageHelper<GetDeviceConfig> {};
struct MessageB : MessageHelper<GetDeviceConfig> {};
// etc...
class MessageHandler {
public:
virtual void handle(MessageA& m);
virtual void handle(MessageB& m);
// etc...
virtual void handle(Message&) {}
};
template<typename ActualMessage>
void MessageHelper<ActualMessage>::dispatch(MessageHandler& handler)
{
handler.handle(static_cast<ActualMessage&>(*this));
}
I'm limited due to the fact that the MessageHelper class is templated. This restricts me in forward declaring the MessageHandler class instead.
Непонятно, почему вы думаете, что наличие шаблона MessageHelper
помешает вам заблаговременно объявить MessageHandler
.