manuK
February 18, 2018, 6:33pm
1
Hello,
I am posting here my question because I did not find any answers on the internet.
I have two classes. An environment and a container one.
In the environment , I have a queue, which is just an array of containers pointer. I fill the queue and try to read it but get an unexpected output. Here is the code
here is the test.h
#ifndef Test_h
#define Test_h
#include "Arduino.h"
class Container
{
public:
Container(String name);
String str();
private:
String _name;
};
class Environment
{
public:
Environment();
void readQueue();
void addQueue(Container* container, int i);
private:
Container* _queue[];
};
#endif
here is the test.cpp
#include "Test.h"
#include "Arduino.h"
Container::Container(String name){
String _name = name;
}
String Container::str(){
return _name;
}
Environment::Environment(){
Container* _queue[4];
}
void Environment::readQueue(){
for (int n=0; n<4; n++)
{
Serial.println(n);
if (_queue[n]==NULL){
Serial.println("empty");
}else{
Serial.println(_queue[n]->str());
}
}
}
void Environment::addQueue(Container* container, int i){
_queue[i] = container;
}
here is my main file
#include <Test.h>
Environment environment;
Container container("test number one");
void setup() {
Serial.begin(9600);
}
void loop() {
environment.addQueue(&container, 1);
environment.readQueue();
delay(100);
Serial.println("-----------");
}
and here is the output I get
0
1
2
2�
3
empty
when I was expecting to get this instead
0
empty
1
test number one
2
empty
3
empty
Any ideas why?
manuK:
Any ideas why?
whoops!
Container::Container(String name) {
String _name = name;
}
manuK
February 18, 2018, 6:59pm
3
I am sorry, I am a beginner. But I don't get your answer. What do you mean by whoops ?
here you create a class with a String member called _name :
class Container
{
public:
Container(String name);
String str();
private:
String _name;
};
in your constructor you create a new local variable called _name :
Container::Container(String name) {
String _name = name;
}
the local variable is destroyed when the constructor ends...
try:
Container::Container(String name) {
_name = name;
}
and assign the argument to the class member, as you probably want to do.
manuK
February 18, 2018, 7:09pm
5
Sorry my mistake. So I change the constructor to avoid create a new local variable.
But my output is weirder. Here is just an extract.
0
⸮⸮⸮Iw⸮⸮⸮⸮⸮ح⸮⸮⸮⸮⸮o⸮⸮7⸮⸮⸮⸮/⸮⸮⸮⸮⸮⸮⸮f⸮⸮⸮⸮⸮⸮_;⸮?⸮⸮M_t⸮⸮⸮⸮p⸮y^o⸮?⸮Y⸮]߫⸮⸮⸮띵/⸮ ⸮}⸮^⸮⸮յ⸮⸮⸮⸮⸮K⸮0
0
0
0
0
0
0
0
⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮9Ha⸮6#⸮Ve⸮!⸮⸮6⸮!ܭ⸮o⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮
manuK:
Sorry my mistake. So I change the constructor to avoid create a new local variable.
But my output is weirder. Here is just an extract.
class Container
{
public:
Container(String name);
String str();
private:
String _name;
};
class Environment
{
public:
Environment();
void readQueue();
void addQueue(Container* container, int i);
private:
Container* _queue[];
};
Container::Container(String name) {
_name = name;
}
String Container::str() {
return _name;
}
Environment::Environment() {
Container* _queue[4];
}
void Environment::readQueue() {
for (int n = 0; n < 4; n++)
{
Serial.println(n);
if (!_queue[n]) {
Serial.println("empty");
} else {
Serial.println(_queue[n]->str());
}
}
}
void Environment::addQueue(Container* container, int i) {
_queue[i] = container;
}
Environment environment;
Container container("test");
void setup() {
Serial.begin(9600);
environment.addQueue(&container, 0);
environment.readQueue();
Serial.println("-----------");
}
void loop() {
}
manuK
February 18, 2018, 8:08pm
7
Ok, thank you for your patience, your code works.
But I still have a few questions :
What is the difference between if (!_queue[n]){
and if (_queue[n] == NULL){
?
Why when I put all the declaration and definition in exterior h and cpp file the program is not working (previous error reappear)?
Also, when i put for example
Serial.println("-----------");
delay(1000);
in the loop function, the program is not working any more also, why?
And a last question, I previously developed my program (who is a kind of super thermostat for a brewery) in python, because I am more familiar with this language and it was more easy for me to write all the unit tests, what is the c++ equivalent of push and pop ? I find out with the std::queue::push() and std::queue::pop() of the queue library, but this is not implemented in arduino. What is the alternative ?
whoops again!
I thought you'd be able to find that one, since you did exactly the same error twice. :
Environment::Environment() {
Container* _queue[4];
}
similarly, this created a 4 element array local to the constructor.
#include "Test.h"
Environment environment;
Container container("test");
void setup() {
Serial.begin(9600);
environment.addQueue(&container, 0);
environment.readQueue();
Serial.println("-----------");
}
void loop() {
}
Test.h:
#ifndef TEST_H
#define TEST_H
#include "Arduino.h"
class Container
{
public:
Container(String name);
String str();
private:
String _name;
};
class Environment
{
public:
Environment();
void readQueue();
void addQueue(Container* container, int i);
private:
Container* _queue[4];
};
#endif
Test.cpp
#include "Test.h"
Container::Container(String name) {
_name = name;
}
String Container::str() {
return _name;
}
Environment::Environment() {
}
void Environment::readQueue() {
for (int n = 0; n < 4; n++)
{
Serial.println(n);
if (!_queue[n]) {
Serial.println("empty");
} else {
Serial.println(_queue[n]->str());
}
}
}
void Environment::addQueue(Container* container, int i) {
_queue[i] = container;
}
To answer your questions,
plain old C style array sizes are not mutable run-time. you can look into std::vector, but on an MCU you will have problems with dynamic allocation and your micro's limited SRAM.
manuK:
What is the difference between
if (!_queue[n]){
and
if (_queue[n] == NULL){
just syntax but C++ is migrating away from NULL (#define NULL 0
) for pointer comparisons.
you should use the preferred keyword nullptr
manuK
February 18, 2018, 9:24pm
10
Ok I start to understand. Thank you for everything.