1

I have spent the better part of today trying to figure out why I can't get this to work...

I have this project where, because of previous design considerations, have implemented a singleton class that initializes a bunch of separate sensors in this system that I am running.

The system was originally built for the Particle Boron, but now I am trying to make it work with the Adafruit Feather M0, so I have had to refactor several things and omit lots of lines of Particle RTOS specific things.

However, in doing this, I find that my singleton class no longer works.

Sensors.h:

.
.
.

class Sensors{

    static Sensors *instance;

public:
    static Sensors *getInstance() {
        if (!instance) {
            instance = new Sensors;
        }
        return instance;
    }

}

private:
    Sensors();

.
.
.

Sensors.cpp:

.
.
.

Sensors::Sensors() : dht22(DHTPIN, DHTTYPE) {
#ifdef PLATFORM_ID
    sensorLog("app.Sensors");
#endif
}

.
.
.

main.ino:

.
.
.

// Sensors
Sensors *Sensors::instance = nullptr;
Sensors *allSensors = allSensors->getInstance();

void setup(){

.
.
.

As I try to compile this with ArduinoISP, no matter what I try, I get the following error:

sketch/main.ino.cpp.o: in function `Sensors::getInstance()':
sketch/lib/Sensors/src/Sensors.h:23: undefined reference to `Sensors::Sensors()'
collect2: error: ld returned 1 exit status
exit status 1
[Error] Exit with code=1

I have tried things like changing the line

instance = new Sensor;

to

instance = new Sensor();

making the instance public, changing the Sensor constructor, but all of this to no avail. Could this be a compiler issue? Why would this work on a Particle board, but not an Adafruit Feather M0?

  • 1
    is the cpp in the same folders as the ino? – Juraj Sep 4 at 4:48
  • 2
    Unlike RTOS, Arduino is single threat and no OS, there is really not have any benefit to implement singleton in Arduino environment... – hcheung Sep 4 at 7:52
  • private: Sensors() is outside your class - and your class lacks the required ; at the end of it. Your code is uncompilable as it stands. – Majenko Sep 4 at 9:48
  • @Majenko, the constructor is used only in getInstance. it can be private and is declared there. the compiler founds it. the error is at linking – Juraj Sep 4 at 12:43
0

Singletons aren't a thing in Arduino. Sure, you could do it, but in general you'd make a class then instantiate a global object for that class. Most often that global object is instantiated in the library itself, not the sketch.

Unless you're using an advanced chip with an RTOS (such as ESP32) and making use of the threads of that RTOS heavily there is no benefit to having a singleton.

But to answer your actual question: it's probably because you are trying to use the Sensors() constructor at a time before the compiler knows what the Sensors() constructor is. You would have to add some form of forward declaration so that the compiler knows what you mean when you talk about the Sensors() constructor. In general a simple:

class Sensors;

at near the top of your header before the class is actually defined can help in these situations;

| improve this answer | |
  • Or the OP can simply move the private contructor from the private section to above the public section. Then it should be private (because there is no modifier above and private is the default) and declared before its usage. – Peter Paul Kiefer Sep 4 at 13:01
  • @PeterPaulKiefer, ordering of class members in the class declaration doesn't matter – Juraj Sep 4 at 13:46
  • @Juraj You are right. Please, forget what I said. I'll leave the comment as an example of ignorance ;-) and to help other not to have the same misconception. Now, I think the main problem is that the getInstance method is implemented in the class definition and the constructor is not (just declared). So, probably it helps also if we move the implementation of thegetInstance() into the cpp file an leave only the signatur declaration in the hpp file. Or is there a reason why this would not work? – Peter Paul Kiefer Sep 5 at 6:08
  • @PeterPaulKiefer, I think the cpp is not compiled, because it is in some folder ignored by IDE – Juraj Sep 5 at 9:20
  • @christopolise Are you still with us? What Juraj mentioned in the answer of my last comment sounds good. The CPP file might not be compiled. Did you investigate in that direction? Juraj mentioned that in a comment for the OP, but I have to apollogize for not having recognized it. – Peter Paul Kiefer Sep 5 at 9:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.