I was wondering the correct method to construct objects for use in the setup and loop scopes. I tried working constructing in the global scope, but I get garbage values printed to serial (probably from misusing pointers)? If I use the new keyword, then it works, but I heard that that is not best practice.
I is there a better way I should do this?
// navigator.cpp
#include "navigator.h"
Navigator::begin(Waypoint* w, int count) {
waypoints = w;
pointCount = count;
next = 0; // start with first waypoint
course = 90; // Notice that initial course is due East
Serial.println('here');
}
-
// navigator.h
#define _navigator_h
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
struct Waypoint {
double lat, lon;
};
class Navigator {
public:
begin(Waypoint* w, int);
};
#endif
-
// TransAt.ino
#include "navigator.h"
Waypoint w = { 43.36, -75.1 }; // These objects must be accessible in both setup() and loop(), but we can't use the new keyword
Navigator nav(); // That means we have to do a lot of the heavy lifting here
uint32_t timer = millis();
void setup() {
nav.begin(&w, 1);
}
void loop()
{
}
1 Answer 1
I tried working constructing in the global scope, but I get garbage values printed to serial ...
Constructors in global scope are called before init
and setup
and thus are probably executing too soon for you. This would account for the garbage printed to serial, because your constructor is printing before the Serial.begin()
call.
You can put constructors in global scope, however they should do fairly trivial things (eg. setting a counter to zero, or a pointer to NULL). Do not rely upon the system being initialized, thus do not call functions like millis
, nor should you be using dynamic memory allocation at this point.
Most classes defer their "real" initialization to a begin
function (eg. Serial.begin
) because it is safe to do that, usually in the setup
function.
Serial.begin(baudrate);
? AlsoNavigator nav();
is kind of function prototype. You can useNavigator nav;