SkylineGodzilla SkylineGodzilla - 1 month ago 6
C++ Question

C++ so why error: no match for 'operator='

So I am just trying to make an array of objects of my custom class bcLED and I am getting the error.
error: no match for 'operator=' (operand types are 'bcLed' and 'bcLed*')

Can some one tell me why? I know it will be something simple.

also why i am here is there a way to create an array of an unspecified length in C++ and then just append it with an new row each time I want to add an object to it?

void PopulateLEDS(){
int i;
bcLed ledArr[17];
for (i = 0; i< 16; i++)
{
ledArr[i] = new bcLed();
ledArr[i].id = i;
ledArr[i].charge = 0;
}
}


OK so i need more help

To avoided creating ten thousand posts I am going to paste the main body of the code so that to see where I am tripping up with the C++ syntax.

the lattest errors are

/Users/bencawley/Documents/Arduino/Test/Bens_Lights/Bens_Lights.ino: In function 'void PopulateLEDS()':
Bens_Lights:49: error: expected primary-expression before 'public'
public:bcLed ledArr[17];
^
Bens_Lights:52: error: 'ledArr' was not declared in this scope
ledArr[i].id = i;
^
/Users/bencawley/Documents/Arduino/Test/Bens_Lights/Bens_Lights.ino: In function 'void BensPattern(uint8_t)':
Bens_Lights:69: error: 'ledArr' was not declared in this scope
strip.setPixelColor(i,0, 0, ledArr[i].charge, 0);
^
Using library Adafruit_NeoPixel at version 1.0.6 in folder: /Users/bencawley/Documents/Arduino/libraries/Adafruit_NeoPixel
exit status 1
expected primary-expression before 'public'


And my code is:

class bcLed{
public:int id;
public:int charge;

void incCharge(int amt)
{
charge = charge+amt;
if(charge >= 255){charge = 255;}
}
};

void setup() {
strip.begin();
strip.show(); // Initialize all pixels to 'off'

PopulateLEDS();
}

void loop() {
// Some example procedures showing how to display to the pixels:
BensPattern(45);

}

void PopulateLEDS(){
int i;
bcLed ledArr[17];
for (i = 0; i< 17; i++)
{
ledArr[i].id = i;
ledArr[i].charge = 0;
}
}

void BensPattern(uint8_t wait)
{
uint16_t i, j;
int rn = rand() % strip.numPixels() ;

for (i = 0; i<strip.numPixels(); i++)
{
strip.setPixelColor(i,0, 0, 0, 0);
}

for (i = 0; i<rn; i++)
{
strip.setPixelColor(i,0, 0, ledArr[i].charge, 0);
ledArr[i].incCharge(1);
}

strip.show();
delay(wait);
}

Answer

new isn't always needed in C++, and definitely not here. new allocates dynamic memory for you if automatic allocation isn't good enough for you. You usually only use new if you want the variable to outlive it's scope. Memory allocated with new must also always be deleted in order to avoid a memory leak. In modern C++, the use of new is even less needed because we have smart pointers.

bcLed ledArr[17];

This already creates 17 bcLeds for you (like how you would use new in C#, requires no cleanup), no need to use new on them. Just work with them.. Your loop condition is wrong too, it's supposed to be < 17.

for (i = 0; i < 17; i++)
{
   ledArr[i].id = i;
   ledArr[i].charge = 0;
}

also why i am here is there a way to create an array of an unspecified length in C++ and then just append it with an new row each time I want to add an object to it?

Yes, that's what a std::vector is for:

#include <vector>
std::vector<bcLed> ledArr(17);

//loop over them:
for(int i = 0; i < ledArr.size(); ++i)
{
  //ledArr[i]
}

//or:
for(std::vector<bcLed>::iterator itr = ledArr.begin() itr != ledArr.end(); ++itr)
{
  //*itr
}

// to insert to the back of the vector use push_back:

bcLed aLed;
ledArr.push_back(aLed);

If you have access to C++11 you can use a range based loop instead and use emplace_back:

#include <vector>
std::vector<bcLed> ledArr(17);

//loop over them, just to iterate:
for(const auto& led : ledArr)
{
  //led.id
  //led.charge
}

//appending to the vector:

ledArr.emplace_back(/*constructor arguments*/);

To answer your comment

ok im going to brave and ask this when you say "if you want the variable to outlive it's scope or you're working with low level memory" I don't understand what any of that means... well mostly I don't understand what you mean by scope or low level memory. Could you explain those? is scope the time that the method runs for?

A scope of a variable is the context in which it is defined. Automatic storage lives until the end of it's scope. Braces { } indicate scope. For example:

void foo()
{
  int x;
  bcLed aLed;
  { //create a new inner scope
    bcLed innerLed;   
  } //scope ends, all automatic variables are destroyed (innerLed in this case)

  //can't use `innerLed` here.

  int new_int = x; 
} // scope ends, same goes, new_int, x, aLed are destroyed.

Really though, a good book will tell you the differences and when they should be used.