mardi 30 octobre 2018

C++ Factory with inheritance

Currently I am in a project where I need to dynamically add and remove sensors to a hardware (Arduino).

In order to do that, I have created a base class named "Sensor" and derivated class for each sensor. This "sensor" class has a virtual method called execute, and this method in overriden on each derivated class, due that each sensor is different, so a different execution implemantation is needed for each type. In this example, I used PIR and DTH11 has derivated classes.

When a sensor needs to be added, the hardware will recieve a string from a server, and from this recieved string, it will create the appropriate sensor. In order to simplyfy things in this questions, I just did it manually on the main() method.

To store the sensors, I am using a std::list, and from time to time, the method execute() will be called.

However, the method of the base class (Sensor) is always executed instead of the delivered classes as shown on the results and expected results below.

class Sensor 
{
    protected:
        int GPIO;
        char* name;   
    public:
        virtual void execute() {std::cout << "This is sensor"} ;
        int getGPIO() const;
        void setGPIO(int);
        char* getName() const;
        void setName(char*);
        Sensor(int sensorGPIO, char* sensorName) {//};
};

class PIR : public Sensor {
    public:
        void execute(){std::cout << "This is PIR"};
        PIR(int gpio) : Sensor(gpio, "pir"){//};
};
class DHT11 : public Sensor {
    public:
        void execute() {std::cout << "This is DHT11"};
        DHT11(int gpio) : Sensor(gpio, "dht11"){//};
};

class SensorFactory 
{
    public:
        SensorFactory(){};
        Sensor createSensor(char* sensorString, int gpio)
        {
            if(strcmp(sensorString, "pir") == 0)
            {
                return PIR(gpio);
            }
            else if(strcmp(sensorString, "dht11") == 0)
            {
                return DTH11(gpio);
            }
        };
};

int main()
{
     std::list<Sensor> sensors;
     SensorFactory factory();
     Sensor s1 = factory.createSensor("pir", 10);
     Sensor s2 = factory.createSensor("dth11", 12);
     sensors.push_front(s1);
     sensors.push_front(s2);

     std::list<Sensor>::iterator i = sensores.begin();
     while (i != sensores.end())
     {
         (i)->execute();
         ++i;
     }

     /* Expected results
        This is PIR
        this is DHT11
     */

     /* Result 
        This is sensor
        This is sensor
     */
}

I have also tried this:

class Sensor 
{
    protected:
        //
    public:
        virtual void execute() = 0;
        //
};

But I get this error:

invalid abstract return type for member function 
Sensor SensorFactory::createSensor(char*, int)

Please keep in mind that I am relatively new to C++, so possibly this is not the approach (implementation) for this problem.

Aucun commentaire:

Enregistrer un commentaire