Лучшее обходное решение функции виртуального шаблона C++ ⇐ C++
Лучшее обходное решение функции виртуального шаблона C++
У меня есть класс ComInterface, в котором есть перегруженная функция send. Эта функция перегружена для многих различных типов перечисляемых классов.
класс ComInterface{ публика: виртуальная недействительная отправка (MotorCommand cmd); виртуальная пустота send (ValveCommand cmd); виртуальная пустота send (ThrottleCommand cmd); }; Тогда у меня есть производный класс CanCom
класс CanCom: public ComInterface{ публика: void send (uint32_t CanID, uint8_t cmd); виртуальная пустота send (MotorCommand cmd) { отправить (1, (uint8_t) cmd); //1 — адрес конкретного двигателя } виртуальная пустота send (ValveCommand cmd) { отправить (2, (uint8_t) cmd); //2 — адрес клапана. } виртуальная пустота send (ThrottleCommand cmd) { отправить (3, (uint8_t) cmd); } }; Это код на данный момент. Поскольку у меня есть много таких классов-перечислений (например, MotorCommand), я бы предпочел использовать шаблон. Что-то вроде:
класс ComInterface{ публика: шаблон виртуальная пустота send (T cmd); }; Затем конкретный адрес будет вставлен с переменной шаблона, как предложено здесь. Функция шаблона C++ связывает тип параметра с целым числом. Итак, что-то вроде [как было предложено Jarod42 в связанном вопросе]
шаблон constexpr uint32_t can_address = [](){ throw "Должно быть специализированным"; }(); шаблон constexpr uint32_t can_address = 1; шаблон constexpr uint32_t can_address = 2; шаблон constexpr uint32_t can_address = 3; шаблон send(T cmd){ send(can_address, (uint8_t) msg); } Но теперь у меня возникла проблема: я не могу использовать шаблоны И виртуальные функции. После некоторых исследований я считаю, что лучший способ решить эту проблему — использовать дизайн, основанный на политике. Итак, ComInterface — это класс шаблона, и существует что-то вроде класса CanImplementation, который передается в качестве параметра шаблона. К сожалению, это означало бы, что тип ComInterface придется адаптировать в каждом месте его использования, что в моем случае невозможно.
Моей следующей идеей было создать новый класс TypeToIDConverter, который преобразует тип в идентификатор. Но тогда этот класс придется снова унаследовать от «TypeToCanIDConverter», и опять же, поскольку он должен быть виртуальным, никакие шаблоны использовать нельзя. Я подумал об использовании обычного переопределения, а затем преобразовать преобразователь базового типа, который будет храниться в ComInterface, в производный класс с помощью static_cast. Однако я не уверен, что это сработает, и это наверняка будет некрасивое решение!
Другие идеи, которые я нашел, — это ошибка типа и принцип посетителя. Однако я не уверен, как бы я их использовал здесь.
Есть ли элегантное решение? Что-то, что мне не нужно писать функцию отправки для каждого типа класса перечисления, но при этом сохраняет общий интерфейс и оставляет место для новых реализаций для других протоколов (например, LinCom или I2CCom)?
Заранее большое спасибо! Эта проблема уже несколько дней не дает мне покоя...
У меня есть класс ComInterface, в котором есть перегруженная функция send. Эта функция перегружена для многих различных типов перечисляемых классов.
класс ComInterface{ публика: виртуальная недействительная отправка (MotorCommand cmd); виртуальная пустота send (ValveCommand cmd); виртуальная пустота send (ThrottleCommand cmd); }; Тогда у меня есть производный класс CanCom
класс CanCom: public ComInterface{ публика: void send (uint32_t CanID, uint8_t cmd); виртуальная пустота send (MotorCommand cmd) { отправить (1, (uint8_t) cmd); //1 — адрес конкретного двигателя } виртуальная пустота send (ValveCommand cmd) { отправить (2, (uint8_t) cmd); //2 — адрес клапана. } виртуальная пустота send (ThrottleCommand cmd) { отправить (3, (uint8_t) cmd); } }; Это код на данный момент. Поскольку у меня есть много таких классов-перечислений (например, MotorCommand), я бы предпочел использовать шаблон. Что-то вроде:
класс ComInterface{ публика: шаблон виртуальная пустота send (T cmd); }; Затем конкретный адрес будет вставлен с переменной шаблона, как предложено здесь. Функция шаблона C++ связывает тип параметра с целым числом. Итак, что-то вроде [как было предложено Jarod42 в связанном вопросе]
шаблон constexpr uint32_t can_address = [](){ throw "Должно быть специализированным"; }(); шаблон constexpr uint32_t can_address = 1; шаблон constexpr uint32_t can_address = 2; шаблон constexpr uint32_t can_address = 3; шаблон send(T cmd){ send(can_address, (uint8_t) msg); } Но теперь у меня возникла проблема: я не могу использовать шаблоны И виртуальные функции. После некоторых исследований я считаю, что лучший способ решить эту проблему — использовать дизайн, основанный на политике. Итак, ComInterface — это класс шаблона, и существует что-то вроде класса CanImplementation, который передается в качестве параметра шаблона. К сожалению, это означало бы, что тип ComInterface придется адаптировать в каждом месте его использования, что в моем случае невозможно.
Моей следующей идеей было создать новый класс TypeToIDConverter, который преобразует тип в идентификатор. Но тогда этот класс придется снова унаследовать от «TypeToCanIDConverter», и опять же, поскольку он должен быть виртуальным, никакие шаблоны использовать нельзя. Я подумал об использовании обычного переопределения, а затем преобразовать преобразователь базового типа, который будет храниться в ComInterface, в производный класс с помощью static_cast. Однако я не уверен, что это сработает, и это наверняка будет некрасивое решение!
Другие идеи, которые я нашел, — это ошибка типа и принцип посетителя. Однако я не уверен, как бы я их использовал здесь.
Есть ли элегантное решение? Что-то, что мне не нужно писать функцию отправки для каждого типа класса перечисления, но при этом сохраняет общий интерфейс и оставляет место для новых реализаций для других протоколов (например, LinCom или I2CCom)?
Заранее большое спасибо! Эта проблема уже несколько дней не дает мне покоя...
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Параметры шаблона вариального шаблона в контексте не подведенного шаблона функции [дубликат]
Anonymous » » в форуме C++ - 0 Ответы
- 8 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Параметры шаблона вариального шаблона в контексте не подведенного шаблона функции [дубликат]
Anonymous » » в форуме C++ - 0 Ответы
- 7 Просмотры
-
Последнее сообщение Anonymous
-