Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
更改一个对象';LinkedList中的s成员更改所有对象 对不起,我对C++很陌生,我正在编写一个ARDIIO草图。< /P>_C++_Oop_C++11_Arduino_Linked List - Fatal编程技术网

更改一个对象';LinkedList中的s成员更改所有对象 对不起,我对C++很陌生,我正在编写一个ARDIIO草图。< /P>

更改一个对象';LinkedList中的s成员更改所有对象 对不起,我对C++很陌生,我正在编写一个ARDIIO草图。< /P>,c++,oop,c++11,arduino,linked-list,C++,Oop,C++11,Arduino,Linked List,我想实现一种面向命令的方法,在这种方法中,我有一个命令队列、一个父虚拟/抽象类命令,并且每个实际命令都从这个类继承 为了实现这个队列,我使用从Arduino的库管理器(某种“库存储”)获得的LinkedList库。因此,我: LinkedList<Command*> queue = new LinkedList<Command*>(); LinkedList队列=新建LinkedList(); 我添加了*因为否则它将无法编译 问题是,我正在使用“new”操作符将命令推

我想实现一种面向命令的方法,在这种方法中,我有一个命令队列、一个父虚拟/抽象类命令,并且每个实际命令都从这个类继承

为了实现这个队列,我使用从Arduino的库管理器(某种“库存储”)获得的LinkedList库。因此,我:

LinkedList<Command*> queue = new LinkedList<Command*>();
LinkedList队列=新建LinkedList();
我添加了*因为否则它将无法编译

问题是,我正在使用“new”操作符将命令推送到队列中。如果我只处理列表中的一个对象,它会正常工作,但目的是在队列中有多个命令,问题是如果我更改实例的成员,它也会更改队列中的所有其他实例,就像所有实例都指向同一个实例一样。当然,变量并不是声明为静态的

我怀疑是因为列表初始化中的**,但老实说,我还没有完全理解C++指针,这只是一个疯狂的猜测。 更新#1:回答molbdnilo请求。下面是一个最小的可复制示例(您需要Luis Llamas创建的LinkedListLib库,可以从Arduino库管理器获得):

#包括
//确定
类命令{
私人:
String state=“NOT_EXEC”;//Estados:NOT_EXEC,NOT_FINISHED,FINISHED
公众:
virtual void init()=0;//Función de inicialización de comando
virtual void exec()=0;//Función de ejeucción del comando
virtual void finish()=0;//Función de finalizado del comando
void setStatus(字符串s){state=s;};
virtual~Command(){};
字符串getStatus(){
返回状态;
}//科曼多庄园酒店
};
类Parpadear:public命令{
私人:
长t;
int c=0;
int stat;
国际密尔;
国际代表;
公众:
Parpadear(整数x,整数y){
密耳=x;
rep=y;
}
void init()重写{
t=millis();
stat=高;
digitalWrite(LED内置,stat);
}
void exec()重写{
如果(毫秒()-t>mil){
stat=stat==高?低:高;
digitalWrite(LED内置,stat);
t=millis();
C++;
}
if(c==rep){
设置状态(“完成”);
}
}
void finish()重写{
}
Parpadear::~Parpadear(){
}
};
//Estados:1=init,2=exec,3=main
常量int INIT=1;//初始化状态
const int EXEC=2;//命令执行状态
常量int MAIN=3;//主循环代码状态
int state=INIT;
初始时间长;
LinkedList队列=LinkedList();
字符串命令结果;
无效设置(){
//伊尼西翁·德阿杜伊诺
pinMode(LED内置,输出);//配置LED表
Serial.begin(9600);
}
void循环(){
//东方公司全球结构控制部部长
开关(状态){
案例初始:
//埃斯塔多斯马奎纳酒店
init_time=millis();//这是一个很好的例子。
state=EXEC;//Realizar transición a ejeucción de comandos。
队列.插入头(新Parpadear(2000,4));
InsertTail(新Parpadear(300,50));
打破
案件执行官:
//可口可乐公司
if(queue.GetSize()>0){
if(queue.GetHead()->getStatus()=“NOT_EXEC”){
queue.GetHead()->init();
queue.GetHead()->setStatus(“未完成”);
}
queue.GetHead()->exec();//ejecta primer comando en la cola
if(queue.GetHead()->getStatus()==“FINISHED”){
//Serial.println(queue.GetHead()->getStatus());
queue.GetHead()->finish();
queue.RemoveAt(0);//Quitar el primer comando de la lista
}
}
打破
主要案例:
打破
}
}
更新#2:关于Botje的问题:

我如何确定这两个实例都在改变

(有关代码参考,请参阅开关盒EXEC)

从父命令类继承的所有命令(在本例中,仅实现类Parpadear)都有一个名为“state”的字符串变量,该变量存储命令的状态,因此每次命令排队时,只有当它完成执行时,该“state”变量才会将其值更改为“FINISHED”(否则将被忽略)“NOT_FINISHED”),这会触发队列从列表中删除命令

使用Arduino的串行监视器工具,我可以看到在排队2个命令后,第一个命令将相应地执行,但一旦第一个命令被删除,第二个命令也会立即被删除。我使用Serial.println为每个命令打印“state”变量,所有这些命令都会导致“FINISHED”“当另一个不应该的时候


还打印了变量“c”,它只是一个计数器,在两种情况下它都等于相同的值(4),因为在第二种情况下“c”甚至还没有被操作过。

更改到另一个库解决了这个问题。具有讽刺意味的是,它是由同一位作者开发的

在这种情况下,我使用的是列表而不是LinkedList,有什么区别吗


可能另一个库已经过时,或者以一种模糊的方式处理指针,但是为了记录,我现在使用的库是“ListLib”,也可以从Arduino库管理器中获得

请阅读,然后创建一个。您是如何确定队列中的所有其他实例也发生了变化的?代码在哪里?谢谢你们的回答,我更新了问题以解决你们的问题。再次感谢大家!
#include <LinkedListLib.h>

// Definiciones
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(){
    
  }
};

// Estados: 1 = init, 2 = exec, 3 = main
const int INIT = 1; // Initialization state
const int EXEC = 2; // Command execution state
const int MAIN = 3; // Main loop code state
int state = INIT;
long init_time;
LinkedList<Command*> queue = LinkedList<Command*>();
String commandResult;


void setup() {
  // Inicialización de Arduino
  pinMode(LED_BUILTIN, OUTPUT); // Configura LED en tabla  
  Serial.begin(9600);

}

void loop() {
  // Máquina de estados para control global de la estructura orientada a comandos
  switch(state){
    case INIT:
      // Inicialización de la máquina de estados
      init_time = millis(); // Obtener el tiempo en el que la máquina de estados se empezó a ejecutar por primera vez.
      state = EXEC; // Realizar transición a ejecución de comandos.
      queue.InsertHead(new Parpadear(2000, 4));
      queue.InsertTail(new Parpadear(300, 50));
      break;
    case EXEC:
      // Ejecución de comandos en cola
      if(queue.GetSize() > 0){
        if(queue.GetHead()->getStatus() == "NOT_EXEC"){
          queue.GetHead()->init();
          queue.GetHead()->setStatus("NOT_FINISHED");
        }
        queue.GetHead()->exec(); // Ejecuta primer comando en la cola
        if(queue.GetHead()->getStatus() == "FINISHED"){
          //Serial.println(queue.GetHead()->getStatus());
          queue.GetHead()->finish();
          queue.RemoveAt(0); // Quitar el primer comando de la lista
        }
      }
      break;
    case MAIN:
      break;
  }

}