jeudi 12 novembre 2020

Changing one object's member in a LinkedList changes all objects

I'm sorry I'm quite new to C++ and i'm coding an Arduino sketch.

I wanted to implement a command-oriented approach, where I have a queue of commands, a parent virtual/abstract class Command, and every actual command inherits from this class.

In order to implement this queue, I'm using a LinkedList library that i got from the Arduino's library manager (some sort of "library store"). So that I have:

LinkedList<Command*> queue = new LinkedList<Command*>();

I added the * because otherwise it won't compile.

The thing is that I'm pushing commands to the queue using the "new" operator. If I'm working with just one object in the list, it works properly, but the intention is to have more than one command in the queue, the problem is that if I change an instance's member, it'll change all the other instances in the queue as well, as if all of them were pointing to the same instance. Of course, the variables are not declared as static.

I suspect it's because of the * in the list initialization, but to be honest, I haven't yet completely understood C++ pointers, and this is just a wild guess.

The key parts of the code are:

    class Command {

  

    private:
      String state = "NOT_EXEC"; // Estados: NOT_EXEC, NOT_FINISHED, FINISHED
      
      public: 
      virtual void init() = 0; // Función de inicialización de comando
      virtual void exec() = 0; // Función de ejecución del comando
      virtual void finish() = 0; // Función de finalizado del comando
      void setStatus(String s){ state = s;};
      virtual ~Command(){};
      String getStatus(){
        return state;
      } // Entrega el estado del comando
      
      
    };

    class Parpadear : public Command{
  private: 
  long t;
  int c = 0;
  int stat;
  int mil;
  int rep;
  
  public:
  Parpadear(int x, int y){
  mil = x;
  rep = y;
  }
  void init() override{
    t = millis();
    stat = HIGH;
    digitalWrite(LED_BUILTIN, stat);
  }

  void exec() override{
   if (millis() - t > mil){
    stat = stat == HIGH ? LOW : HIGH; 
    digitalWrite(LED_BUILTIN, stat);
    t = millis();
    c++;
    }

    if(c == rep){
      setStatus("FINISHED");
    }
  }

  void finish() override{

  }

  Parpadear::~Parpadear(){
    
  }
};

    queue.InsertHead(new Parpadear(2000, 4));
      queue.InsertTail(new Parpadear(300, 50));

Aucun commentaire:

Enregistrer un commentaire