Фабричный шаблон на Arduino
Я хочу создать шаблон фабрики для определения того, какой из N объектов подключен к моему порту Serial
. Предполагая, что каждый объект имеет уникальный ответ на входной поток "Какая это тема?"
, как мне заставить мой класс ScienceFactory
создать мои подклассы Science
?
ПРАВКА 2 Для ясности,
- Arduino отправляет
запрос идентификации
на устройство. - Устройство отвечает
строкой идентификации
- Arduino получает
строку идентификации
- Arduino создает правильный
Science Child
Рассмотрев различные примеры, мне удалось получить следующий скелет кода:
class ScienceFactoy
{
public:
enum Subject {Biology, Chemistry, Physics};
enum Subject Topic;
bool GetTopic();
};
bool ScienceFactoy::GetTopic()
{
Serial.println("What Topic is this?");
/*The Device will respond with "Biology", "Chemestry" or "Physics"
over Serial*/
Topic=Biology;
/*Instead of writing the Serial.read() logic,
let's pretend the device is a Biology device*/
if(Topic==Biology)
{
//Создать класс биологии
return true;
}
if(Topic==Chemistry)
{
//Создать класс по химии
return true;
}
if(Topic==Physics)
{
//Создать класс по физике
return true;
}
else
{
return false;
}
}
class Science
{
public:
enum Subject {Biology, Chemistry, Physics};
enum Subject Topic;
//bool takeAttendance()
//виртуальная пустота TestStudents();
//виртуальный void PopQuiz();
virtual void Free() = 0;
};
class Biology : public Science
{
public:
Biology(){Serial.println("Ready For Bio");}
//bool DissectFrogs(){}
};
class Chemistry : public Science
{
public:
Chemistry(){Serial.println("Ready For Chem");}
//boolСмешанныеХимическиеВещества(){}
};
class Physics : public Science
{
public:
Physics(){Serial.println("Ready For Physics");}
//boolOpticsLab(){}
};
Science ConnectedClass;
void setup() {
Serial.begin(9600);
ScienceFactory ClassAtSerialPort; /*(Something happens that redefines
ClassAtSerialPort to be the correct class)*/
/*SerialOut "Ready For Bio\n" should happen here*/
ConnectedClass=ClassAtSerialPort;
}
void loop() {
if(ConnectedClass.Topic==Biology){DissectFrogs();};
}
Однако я не знаю, что делать дальше, так как мой код специфичен для Arduino. (Изменить код так, чтобы он компилировался)
@ATE-ENGE, 👍-1
1 ответ
Лучший ответ:
Это не простое решение из-за структуры ваших классов Factory и Science.
Ваш класс Science должен содержать фактический экземпляр самого себя для использования, когда цикл хочет вызвать потомков. Этот экземпляр будет называться 'device' в моем примере.
class Science
{
public:
enum Subject {Biology, Chemistry, Physics};
enum Subject Topic;
//bool takeAttendance()
//virtual void TestStudents();
//virtual void PopQuiz();
virtual void Free() = 0;
Science* device;
};
В вашем вызове GetTopic() вам затем нужно создать экземпляр фактического дочернего класса
if(Topic==Biology)
{
//Создать класс биологии
device = new Biology(); // с соответствующими параметрами
return true;
}
Затем в вашей настройке() вам придется использовать класс, который был создан
ConnectedClass=ClassAtSerialPort.device;
Таким образом, в коде loop() вы вызываете метод, специфичный для устройства.
void loop() {
if(ConnectedClass.Topic==Biology){connectedClass.doScience();};
}
В вашем подходе есть проблема, которую вам все еще нужно решить. Опора на полиморфизм, как правило, делается путем создания общего метода в родителе, который переопределяют все дочерние классы (например, doScience()
), и каждый дочерний класс делает то, что уместно. У вас могут быть методы, специфичные для класса, но тогда вам, скорее всего, сначала нужно будет привести устройство к определенному классу.
- Какие накладные расходы и другие соображения существуют при использовании структуры по сравнению с классом?
- Массив динамического размера в качестве члена класса
- Как перебрать объекты или передать объект функции?
- C++ Undefined reference to 'Class:Function()'
- Прерывания внутри класса, связанные с функцией класса
- Недопустимое использование нестатической функции-члена
- Вызов функций одного класса из другого класса — Обратный вызов
- Библиотеки Arduino: объявляете ли вы переменные публичными?