Справка по созданию производных классов в заголовках
Вот небольшая проблема, с которой я столкнулся, когда пытался сделать этот небольшой файл заголовка Devices.h
:
Можно ли использовать шаблоны с абстрактными классами ? Если да, то как и как я могу использовать этот абстрактный класс для получения другого класса ?
Вот содержимое файла заголовка :
#ifndef Devices_h
#define Devices_h
/* Начальная сборка для MCUOS
Любой может редактировать это в соответствии с потребностями своего устройства */
#include "Arduino.h"
template < typename datatype>
class Device_Handler
{
// a class to handle devices
public:
virtual void write_to_device(datatype *send_data)= 0; // write data to device
virtual void read_from_device(datatype *store_location)= 0 ; // read data from device to location
virtual void clear_device() = 0; // clear device state
};
class Serial_Handler:public Device_Handler<char*>
{
public:
void write_to_device(char *send_data);
void read_from_device(char *store_location);
void clear_device();
};
void Serial_Handler<char*>::write_to_device(char *send_data){
Serial.println(*send_data);
}
void Serial_Handler<char*>::read_from_device(char *store_location){
*store_location = Serial.read();
}
void Serial_Handler::clear_device(){
Serial.flush();
}
#endif
Это небольшой проект, который я сейчас пробую дома (эта штука MCUOS там), также рассматривая его как возможность обучения. Я не уверен, что правильно написал код в заголовке. Сначала я создал класс Device_Handler и использовал его в своем скетче для создания
класса Serial_Handler, но затем он показал ошибку, что компилятор ожидал имя класса перед символом '{' прямо в том месте, где я начал писать код для производного класса. Поэтому я решил перенести код производного класса в заголовок, но решил обратиться к вам за советом, прежде чем идти дальше, так как боюсь, что возникнет еще больше ошибок, а также потому, что я в некотором роде новичок в C++.
Заранее спасибо !
EDIT : Я также сомневаюсь, что это было потому, что я написал комментарий рядом с начальной строкой абстрактного класса, так как синтаксический маркер здесь показывал комментарии в цвете.
Edit: Я решил эту проблему там (это было из-за неуместного комментария), но появилась новая проблема, в которой говорилось, что она ожидала инициализатора до того, как ' Вот где мое настоящее.
Мои фрагменты основной проблемы:
void Serial_Handler<char>::write_to_device(char *send_data){
Serial.println(*send_data);
}
void Serial_Handler<char*>::read_from_device(char *store_location){
*store_location = Serial.read();
}
Я сомневаюсь, что они смогут обрабатывать длинные предложения или иметь синтаксические ошибки.
Правка Я решил двигаться вперед, несмотря на ошибки. Вот как я переделал свой файл заголовка:
#ifndef Devices_h
#define Devices_h
/* Начальная сборка для MCUOS
Любой может редактировать это в соответствии с потребностями своего устройства */
#include "Arduino.h"
template < typename datatype>
class Device_Handler
{
// класс для обработки устройств
public:
virtual void write_to_device(datatype *send_data)= 0; // запись данных на устройство
virtual void read_from_device(datatype *store_location)= 0 ; // read data from device to location
virtual void clear_device() = 0; // clear device state
};
class Serial_Handler:public Device_Handler<char*>
{
public:
void write_to_device(char *send_data);
void read_from_device(char *store_location);
void clear_device();
};
void Serial_Handler::write_to_device(char *send_data){
Serial.println(*send_data);
}
void Serial_Handler::read_from_device(char *store_location){
*store_location = Serial.read();
}
void Serial_Handler::clear_device(){
Serial.flush();
}
#endif
Вот код скетча:
#include <Devices.h>
Serial_Handler myserial;
char storage = '\0';
char test_string[] = "Hello";
void setup() {
Serial.begin(9600);
myserial.write_to_device(test_string);
myserial.read_from_device(&storage);
}
void loop() {
// put your main code here, to run repeatedly:
}
(Я знаю, что код там также может быть неисправен) и возникают ошибки:
Arduino: 1.8.13 (Windows 10), Board: "Arduino Uno"
Devices_Test:3:16: error: cannot declare variable 'myserial' to be of abstract type 'Serial_Handler'
Serial_Handler myserial;
^~~~~~~~
In file included from C:\Users\<smbdy>\Documents\Arduino\Devices_Test\Devices_Test.ino:1:0:
C:\Users\<smbdy>\Documents\Arduino\libraries\Devices/Devices.h:19:7: note: because the following virtual functions are pure within 'Serial_Handler':
class Serial_Handler:public Device_Handler<char*>
^~~~~~~~~~~~~~
C:\Users\<smbdy>\Documents\Arduino\libraries\Devices/Devices.h:14:16: note: void Device_Handler<datatype>::write_to_device(datatype*) [with datatype = char*]
virtual void write_to_device(datatype *send_data)= 0; // write data to device
^~~~~~~~~~~~~~~
C:\Users\<smbdy>\Documents\Arduino\libraries\Devices/Devices.h:15:16: note: void Device_Handler<datatype>::read_from_device(datatype*) [with datatype = char*]
virtual void read_from_device(datatype *store_location)= 0 ; // read data from device to location
^~~~~~~~~~~~~~~~
exit status 1
cannot declare variable 'myserial' to be of abstract type 'Serial_Handler'
Как я должен решить эту проблему?
1 ответ
Лучший ответ:
Вы находитесь на пути, но он нуждается в некоторых корректировках:
template < typename datatype>
class Device_Handler
{
// класс для обработки устройств
public:
virtual void write_to_device(datatype *send_data)= 0; // запись данных на устройство
virtual void read_from_device(datatype *store_location)= 0 ; // read data from device to location
virtual void clear_device() = 0; // очистить состояние устройства
};
class Serial_Handler:public Device_Handler<char> // instead of char*
{
public:
void write_to_device(char *send_data) override;
void read_from_device(char *store_location) override;
void clear_device() override;
};
void Serial_Handler::write_to_device(char *send_data){ // Это не шаблон, поэтому никакой специализации шаблона
Serial.println(*send_data);
}
void Serial_Handler::read_from_device(char *store_location){
*store_location = Serial.read();
}
void Serial_Handler::clear_device(){
Serial.flush();
}
Альтернатива такова:
template < typename datatype>
class Device_Handler
{
// класс для обработки устройств
public:
virtual void write_to_device(datatype send_data)= 0; // запись данных на устройство
virtual void read_from_device(datatype store_location)= 0 ; // чтение данных с устройства на место
virtual void clear_device() = 0; // очистить состояние устройства
};
class Serial_Handler:public Device_Handler<char*>
{
public:
void write_to_device(char *send_data) override;
void read_from_device(char *store_location) override;
void clear_device() override;
};
Я все продумал.. Спасибо!, @Sam Ruben Abraham
Я отредактировал свой проект, и он находится на Github :https://github.com/Coder-X15/MCUOS, @Sam Ruben Abraham
- Как использовать SPI на Arduino?
- Библиотека DHT.h не импортируется
- Светодиоды: разница между общим анодом и общим катодом
- Как повторить кусок кода
- Почему эта программа на C++ не может прочитать Serial.write() моего arduino?
- Как изменить переменную при нажатии кнопки, подключенной к контакту 2
- Отображение двоичных данных на светодиодах
- Корпус кнопки и переключателя
Serial_Handler не является шаблоном, поэтому вы не должны использовать SerialHandler **<...>** ::write_to_device / чтение с устройства, @KIIV
Я отредактировал его. Спасибо @KIIV, @Sam Ruben Abraham
Теперь я столкнулся с другой проблемой., @Sam Ruben Abraham
Я определил производные определения классов для виртуальных функций как класс "Device_Handler", но все равно возникла ошибка... вот что меня сейчас беспокоит., @Sam Ruben Abraham
Ну, очевидно, что переопределения не совпадают с теми чисто виртуальными методами в родительском, @KIIV
@KIIV как же так получилось ? Я хотел бы немного это понять.., @Sam Ruben Abraham
Кроме того, я надеюсь, вы знаете, что я немного новичок":), @Sam Ruben Abraham
`Тип данных "- это " char*", который приводит к char ** send_data и т. Д. Но не волнуйся, я не заметил этого намного раньше, @KIIV
Давайте [продолжим это обсуждение в чате](https://chat.stackexchange.com/rooms/123302/discussion-between-sam-ruben-abraham-and-kiiv)., @Sam Ruben Abraham