user67696: Here's a small problem I encountered while I was trying to make this small header file Devices.h:

Is it possible to use templates with abstract classes ? If yes, how and how can I use that abstract class to derive another class ?

Here's the contents of the header file :
#ifndef Devices_h
#define Devices_h

/* Initial build for MCUOS 
Anybody can edit this according to their device needs */ 

#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

This is a small project I am trying at home nowadays (that MCUOS thing up there), also considering it a learning opportunity. I am not sure if I wrote the code in the header the right way. Initially, I made the Device_Handler class and used it in my sketch to craft the Serial_Handler class, but then it showed an error that the compiler expected a class name before the '{' character right at the place where I started writing the code for the derived class. Thus I decided to move the code for the derived class to the header, but I decided to seek your advice before heading further as I fear that more errors may come up and as I am kind of a beginner at C++.
Thanks in advance !
EDIT : I also doubt if it was because I wrote a comment near the starting line of the abstract class as the syntax highlighter here showed the comments in colour.
Edit: I resolved the issue up there (it was due to the misplaced comment), but a new issue has popped up saying that it expected an initialiser before the '<' token at the places where I had defined the functions in the derived class. This is where my actual is.
My snippets of main concern:
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();
}

I doubt if these will be able to handle long sentences or have syntax errors.
Edit
I decided to move forward despite errors. Here's how I remade my header file:
#ifndef Devices_h
#define Devices_h

/* Initial build for MCUOS 
Anybody can edit this according to their device needs */ 

#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::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

Here's the sketch code:
#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:

}

(I know that the code up there may also be faulty)
and errors come up:
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'


How should I resolve this?

user23841: You are on the track, but it needs some adjustments:
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> // 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){ // It's not template, so no template specialization
        Serial.println(*send_data);
 }

void Serial_Handler::read_from_device(char *store_location){
       *store_location = Serial.read();
}

void Serial_Handler::clear_device(){
        Serial.flush(); 
}

The alternative is:
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) override;
       void read_from_device(char *store_location) override;
       void clear_device() override;
};


67696: <p>Here's a small problem I encountered while I was trying to make this small header file <code>Devices.h</code>:</p>
<blockquote>
<p>Is it possible to use templates with abstract classes ? If yes, how and how can I use that abstract class to derive another class ?</p>
</blockquote>
<p>Here's the contents of the header file :</p>
<pre><code>#ifndef Devices_h
#define Devices_h

/* Initial build for MCUOS 
Anybody can edit this according to their device needs */ 

#include &quot;Arduino.h&quot;

template &lt; typename datatype&gt;

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&lt;char*&gt;
{
   public:
          void write_to_device(char *send_data);
          void read_from_device(char *store_location);
          void clear_device();
};


void Serial_Handler&lt;char*&gt;::write_to_device(char *send_data){
        Serial.println(*send_data);
 }

void Serial_Handler&lt;char*&gt;::read_from_device(char *store_location){
       *store_location = Serial.read();
}

void Serial_Handler::clear_device(){
        Serial.flush(); 
}


#endif
</code></pre>
<p>This is a small project I am trying at home nowadays (that MCUOS thing up there), also considering it a learning opportunity. I am not sure if I wrote the code in the header the right way. Initially, I made the <code>Device_Handler</code> class and used it in my sketch to craft the <code>Serial_Handler</code> class, but then it showed an error that the compiler expected a class name before the '{' character right at the place where I started writing the code for the derived class. Thus I decided to move the code for the derived class to the header, but I decided to seek your advice before heading further as I fear that more errors may come up and as I am kind of a beginner at C++.</p>
<p>Thanks in advance !</p>
<p>EDIT : I also doubt if it was because I wrote a comment near the starting line of the abstract class as the syntax highlighter here showed the comments in colour.</p>
<p><strong>Edit</strong>: I resolved the issue up there (it was due to the misplaced comment), but a new issue has popped up saying that it expected an initialiser before the '&lt;' token at the places where I had defined the functions in the derived class. This is where my actual is.</p>
<p>My snippets of main concern:</p>
<pre><code>void Serial_Handler&lt;char&gt;::write_to_device(char *send_data){
        Serial.println(*send_data);
 }

void Serial_Handler&lt;char*&gt;::read_from_device(char *store_location){
       *store_location = Serial.read();
}
</code></pre>
<p>I doubt if these will be able to handle long sentences or have syntax errors.</p>
<p><strong>Edit</strong>
I decided to move forward despite errors. Here's how I remade my header file:</p>
<pre><code>#ifndef Devices_h
#define Devices_h

/* Initial build for MCUOS 
Anybody can edit this according to their device needs */ 

#include &quot;Arduino.h&quot;

template &lt; typename datatype&gt;
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&lt;char*&gt;
{
   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
</code></pre>
<p>Here's the sketch code:</p>
<pre><code>#include &lt;Devices.h&gt;

Serial_Handler myserial;
char storage = '\0';
char test_string[] = &quot;Hello&quot;;

void setup() {
  Serial.begin(9600);
  myserial.write_to_device(test_string);
  myserial.read_from_device(&amp;storage);
}

void loop() {
  // put your main code here, to run repeatedly:

}
</code></pre>
<p>(I know that the code up there may also be faulty)
and errors come up:</p>
<pre><code>Arduino: 1.8.13 (Windows 10), Board: &quot;Arduino Uno&quot;
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\&lt;smbdy&gt;\Documents\Arduino\Devices_Test\Devices_Test.ino:1:0:

C:\Users\&lt;smbdy&gt;\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&lt;char*&gt;

       ^~~~~~~~~~~~~~

C:\Users\&lt;smbdy&gt;\Documents\Arduino\libraries\Devices/Devices.h:14:16: note:     void Device_Handler&lt;datatype&gt;::write_to_device(datatype*) [with datatype = char*]

   virtual void write_to_device(datatype *send_data)= 0; // write data to device

                ^~~~~~~~~~~~~~~

C:\Users\&lt;smbdy&gt;\Documents\Arduino\libraries\Devices/Devices.h:15:16: note:     void Device_Handler&lt;datatype&gt;::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'

</code></pre>
<p>How should I resolve this?</p>
 23841: <p>You are on the track, but it needs some adjustments:</p>
<pre><code>template &lt; typename datatype&gt;
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&lt;char&gt; // 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){ // It's not template, so no template specialization
        Serial.println(*send_data);
 }

void Serial_Handler::read_from_device(char *store_location){
       *store_location = Serial.read();
}

void Serial_Handler::clear_device(){
        Serial.flush(); 
}
</code></pre>
<p>The alternative is:</p>
<pre><code>template &lt; typename datatype&gt;
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&lt;char*&gt;
{
   public:
       void write_to_device(char *send_data) override;
       void read_from_device(char *store_location) override;
       void clear_device() override;
};
</code></pre>
