1

So I'm coming from the C# word trying to program my Particle Photon in C++. I'm trying to make use of a class to help organize the data better.

I made a definition of a class called Lane:

#ifndef Lane_h
#define Lane_h
#include "application.h"

class Lane {

 public:

  Lane(int sensorId, String laneName);
  Lane();

  int
    readSensor(void),
    getWinningOrder(void);

  bool
    hasFinished(void);

  void
    setWinningOrder(int order);

  String
    getName();

  int
    winningOrder;


 private:
    int 
        sensor;

    String  
        name;

};

#endif

Then I made the cpp file:

#include "Lane.h"
#include "application.h"

Lane::Lane(int sensorId, String laneName){
    sensor = sensorId;
    name = laneName;
    winningOrder = 0;
}

Lane::Lane(){
    winningOrder = 0;
}

int Lane::readSensor(){
    int value = analogRead(sensor);
    return value;
}

String Lane::getName(){
    return name;
}

bool Lane::hasFinished(void){
    Particle.publish("DEBUG", name + " has a winning order of: " + String(winningOrder));
    return winningOrder != 0;
}

So far so good.

Now in my .ino file that Particle executes the loop in I read from and set my field. (I've slightly condensed this file to make it easier to read.)

// This #include statement was automatically added by the Particle IDE.
#include "Lane.h"

Lane lanes[] = {
    Lane(A5, "Lane 1"), 
    Lane(A4, "Lane 2"), 
    Lane(A3, "Lane 3"), 
    Lane(A2, "Lane 4")
    };
int winningPlace = 1;

void setup() {

}

void loop() {
    for (uint32_t i = 0; i < arraySize(lanes); i++) {
        Lane lane = lanes[i];
        int value = lane.readSensor();

        if(value + sensitivity < initalValues[i] && !lane.hasFinished()){
            Particle.publish("DEBUG", lane.getName() + " pre-set field value is " + lane.winningOrder);
            lane.winningOrder = winningPlace++;
            Particle.publish("DEBUG", lane.getName() + " set field value is " + lane.winningOrder);
        }

    }
}

The first time through the loop the pre-set debug value returns 0 and after set value returns 1 as expected. The next time through the loop it enters the if statement dispute !lane.hasFinished(). The pre-set returns 0 as if it was looking at a new object or something. What am I missing here? Why is the field's value not persisting on the object between cycle's in the loop?

Simon The Cat
  • 604
  • 1
  • 8
  • 22

2 Answers2

1
Lane lane = lanes[i];

makes a copy of lanes[i] - any modification to lane won't affect the element. Try a reference:

Lane &lane = lanes[i];

lane is an alias for lanes[i]. Using lane is as if you were using lanes[i] and by assigning to lane.winningOrder, you'll actually assign to the referenced lanes[i]'s winningOrder. There are no copies.

Also start using member initialization lists instead of assignments and const qualifiers for member functions.

Community
  • 1
  • 1
LogicStuff
  • 19,397
  • 6
  • 54
  • 74
1

Because you're creating a new object each time.

Lane lane = lanes[i];

This creates a new instance of the Lane class called "lane", whose contents are copy-constructed from lanes[i].

Then, the rest of the loop works with this lane object. It's contents get twiddled, as needed, and afterwards, this object gets destroyed.

Next time through the loop you make another copy of the same, still unused object.

Changing it to a reference should get your desired behavior.

Lane &lane = lanes[i];
Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148