C++ Singleton constructor is not called











up vote
0
down vote

favorite












Dear StackOverflowers,



I made a singleton class called Log, but it does not call the constructor. The class is used to print Serial commands depending on m_LogLevel. I want the constructor to be called once when getInstance() is called for the first time. For some reason though, the constructor never seems to be called, what am I doing wrong?



Thanks in advance!



Log.h:



class Log {

private:
int m_LogLevel = LOGLEVEL;
static Log* instance;
Log();
~Log();

public:
static Log* getInstance();
void debug(String);
};


Log.cpp:



Log* Log::instance = nullptr;

Log::Log() {
DEBUG_PRINT("Log level: ");
DEBUG_PRINTLN(m_LogLevel);
}

Log::~Log() {
}

Log* Log::getInstance() {
if (instance == 0) {
instance = new Log();
}
return instance;
}

void Log::debug(String message) {
if(m_LogLevel >= LogLevelDebug) {
DEBUG_PRINT("[DEBUG]: ");
DEBUG_PRINTLN(message);
}


}



main.cpp:



#define DEBUG_PRINT(x)  Serial.print (x)
#define DEBUG_PRINTLN(x) Serial.println (x)
#define LOGLEVEL 3

#include <Arduino.h>
#include "Log.h"

Log* pLog = Log::getInstance();

void setup() {
Serial.begin(115200);
pLog->debug("Hello world");
}

void loop() {
}









share|improve this question




















  • 1




    Worth looking at (related) stackoverflow.com/a/1008289/3807729
    – Galik
    Nov 10 at 13:11






  • 2




    To create your Compilable, Minimal, Complete, and Verifiable Example, please be sure to include a main() function and all include statements so that others can cut and paste your code and compile it without having to do any additional typing. This helps us help you. If you can make your problem as simple as possible while still creating the failure, it will help us isolate the issues that will make your code work correctly.
    – John Murray
    Nov 10 at 13:28






  • 2




    Can you confirm that your code is not multithreaded (because instance is not atomic so that there could be a data race) ? Also, can you make the same test by using cout instead of your DEBUG_XXX, just to be sure that it's just a problem in the output ? FInally, could you show how you use your getInstance() ?
    – Christophe
    Nov 10 at 13:40






  • 1




    Log* Log::instance = 0; is wrong! You should assign pointers with nullptr instead of just 0....
    – Ruks
    Nov 10 at 13:40








  • 1




    I suspect that the pLog global is initialized after the code tries to access the instance. By using a global variable you are subverting the only thing that makes singletons better than a global variable - namely guaranteed construction before the first use.
    – Michael Veksler
    Nov 10 at 14:02















up vote
0
down vote

favorite












Dear StackOverflowers,



I made a singleton class called Log, but it does not call the constructor. The class is used to print Serial commands depending on m_LogLevel. I want the constructor to be called once when getInstance() is called for the first time. For some reason though, the constructor never seems to be called, what am I doing wrong?



Thanks in advance!



Log.h:



class Log {

private:
int m_LogLevel = LOGLEVEL;
static Log* instance;
Log();
~Log();

public:
static Log* getInstance();
void debug(String);
};


Log.cpp:



Log* Log::instance = nullptr;

Log::Log() {
DEBUG_PRINT("Log level: ");
DEBUG_PRINTLN(m_LogLevel);
}

Log::~Log() {
}

Log* Log::getInstance() {
if (instance == 0) {
instance = new Log();
}
return instance;
}

void Log::debug(String message) {
if(m_LogLevel >= LogLevelDebug) {
DEBUG_PRINT("[DEBUG]: ");
DEBUG_PRINTLN(message);
}


}



main.cpp:



#define DEBUG_PRINT(x)  Serial.print (x)
#define DEBUG_PRINTLN(x) Serial.println (x)
#define LOGLEVEL 3

#include <Arduino.h>
#include "Log.h"

Log* pLog = Log::getInstance();

void setup() {
Serial.begin(115200);
pLog->debug("Hello world");
}

void loop() {
}









share|improve this question




















  • 1




    Worth looking at (related) stackoverflow.com/a/1008289/3807729
    – Galik
    Nov 10 at 13:11






  • 2




    To create your Compilable, Minimal, Complete, and Verifiable Example, please be sure to include a main() function and all include statements so that others can cut and paste your code and compile it without having to do any additional typing. This helps us help you. If you can make your problem as simple as possible while still creating the failure, it will help us isolate the issues that will make your code work correctly.
    – John Murray
    Nov 10 at 13:28






  • 2




    Can you confirm that your code is not multithreaded (because instance is not atomic so that there could be a data race) ? Also, can you make the same test by using cout instead of your DEBUG_XXX, just to be sure that it's just a problem in the output ? FInally, could you show how you use your getInstance() ?
    – Christophe
    Nov 10 at 13:40






  • 1




    Log* Log::instance = 0; is wrong! You should assign pointers with nullptr instead of just 0....
    – Ruks
    Nov 10 at 13:40








  • 1




    I suspect that the pLog global is initialized after the code tries to access the instance. By using a global variable you are subverting the only thing that makes singletons better than a global variable - namely guaranteed construction before the first use.
    – Michael Veksler
    Nov 10 at 14:02













up vote
0
down vote

favorite









up vote
0
down vote

favorite











Dear StackOverflowers,



I made a singleton class called Log, but it does not call the constructor. The class is used to print Serial commands depending on m_LogLevel. I want the constructor to be called once when getInstance() is called for the first time. For some reason though, the constructor never seems to be called, what am I doing wrong?



Thanks in advance!



Log.h:



class Log {

private:
int m_LogLevel = LOGLEVEL;
static Log* instance;
Log();
~Log();

public:
static Log* getInstance();
void debug(String);
};


Log.cpp:



Log* Log::instance = nullptr;

Log::Log() {
DEBUG_PRINT("Log level: ");
DEBUG_PRINTLN(m_LogLevel);
}

Log::~Log() {
}

Log* Log::getInstance() {
if (instance == 0) {
instance = new Log();
}
return instance;
}

void Log::debug(String message) {
if(m_LogLevel >= LogLevelDebug) {
DEBUG_PRINT("[DEBUG]: ");
DEBUG_PRINTLN(message);
}


}



main.cpp:



#define DEBUG_PRINT(x)  Serial.print (x)
#define DEBUG_PRINTLN(x) Serial.println (x)
#define LOGLEVEL 3

#include <Arduino.h>
#include "Log.h"

Log* pLog = Log::getInstance();

void setup() {
Serial.begin(115200);
pLog->debug("Hello world");
}

void loop() {
}









share|improve this question















Dear StackOverflowers,



I made a singleton class called Log, but it does not call the constructor. The class is used to print Serial commands depending on m_LogLevel. I want the constructor to be called once when getInstance() is called for the first time. For some reason though, the constructor never seems to be called, what am I doing wrong?



Thanks in advance!



Log.h:



class Log {

private:
int m_LogLevel = LOGLEVEL;
static Log* instance;
Log();
~Log();

public:
static Log* getInstance();
void debug(String);
};


Log.cpp:



Log* Log::instance = nullptr;

Log::Log() {
DEBUG_PRINT("Log level: ");
DEBUG_PRINTLN(m_LogLevel);
}

Log::~Log() {
}

Log* Log::getInstance() {
if (instance == 0) {
instance = new Log();
}
return instance;
}

void Log::debug(String message) {
if(m_LogLevel >= LogLevelDebug) {
DEBUG_PRINT("[DEBUG]: ");
DEBUG_PRINTLN(message);
}


}



main.cpp:



#define DEBUG_PRINT(x)  Serial.print (x)
#define DEBUG_PRINTLN(x) Serial.println (x)
#define LOGLEVEL 3

#include <Arduino.h>
#include "Log.h"

Log* pLog = Log::getInstance();

void setup() {
Serial.begin(115200);
pLog->debug("Hello world");
}

void loop() {
}






c++ constructor singleton






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 10 at 13:40

























asked Nov 10 at 13:00









Daan van Driel

525




525








  • 1




    Worth looking at (related) stackoverflow.com/a/1008289/3807729
    – Galik
    Nov 10 at 13:11






  • 2




    To create your Compilable, Minimal, Complete, and Verifiable Example, please be sure to include a main() function and all include statements so that others can cut and paste your code and compile it without having to do any additional typing. This helps us help you. If you can make your problem as simple as possible while still creating the failure, it will help us isolate the issues that will make your code work correctly.
    – John Murray
    Nov 10 at 13:28






  • 2




    Can you confirm that your code is not multithreaded (because instance is not atomic so that there could be a data race) ? Also, can you make the same test by using cout instead of your DEBUG_XXX, just to be sure that it's just a problem in the output ? FInally, could you show how you use your getInstance() ?
    – Christophe
    Nov 10 at 13:40






  • 1




    Log* Log::instance = 0; is wrong! You should assign pointers with nullptr instead of just 0....
    – Ruks
    Nov 10 at 13:40








  • 1




    I suspect that the pLog global is initialized after the code tries to access the instance. By using a global variable you are subverting the only thing that makes singletons better than a global variable - namely guaranteed construction before the first use.
    – Michael Veksler
    Nov 10 at 14:02














  • 1




    Worth looking at (related) stackoverflow.com/a/1008289/3807729
    – Galik
    Nov 10 at 13:11






  • 2




    To create your Compilable, Minimal, Complete, and Verifiable Example, please be sure to include a main() function and all include statements so that others can cut and paste your code and compile it without having to do any additional typing. This helps us help you. If you can make your problem as simple as possible while still creating the failure, it will help us isolate the issues that will make your code work correctly.
    – John Murray
    Nov 10 at 13:28






  • 2




    Can you confirm that your code is not multithreaded (because instance is not atomic so that there could be a data race) ? Also, can you make the same test by using cout instead of your DEBUG_XXX, just to be sure that it's just a problem in the output ? FInally, could you show how you use your getInstance() ?
    – Christophe
    Nov 10 at 13:40






  • 1




    Log* Log::instance = 0; is wrong! You should assign pointers with nullptr instead of just 0....
    – Ruks
    Nov 10 at 13:40








  • 1




    I suspect that the pLog global is initialized after the code tries to access the instance. By using a global variable you are subverting the only thing that makes singletons better than a global variable - namely guaranteed construction before the first use.
    – Michael Veksler
    Nov 10 at 14:02








1




1




Worth looking at (related) stackoverflow.com/a/1008289/3807729
– Galik
Nov 10 at 13:11




Worth looking at (related) stackoverflow.com/a/1008289/3807729
– Galik
Nov 10 at 13:11




2




2




To create your Compilable, Minimal, Complete, and Verifiable Example, please be sure to include a main() function and all include statements so that others can cut and paste your code and compile it without having to do any additional typing. This helps us help you. If you can make your problem as simple as possible while still creating the failure, it will help us isolate the issues that will make your code work correctly.
– John Murray
Nov 10 at 13:28




To create your Compilable, Minimal, Complete, and Verifiable Example, please be sure to include a main() function and all include statements so that others can cut and paste your code and compile it without having to do any additional typing. This helps us help you. If you can make your problem as simple as possible while still creating the failure, it will help us isolate the issues that will make your code work correctly.
– John Murray
Nov 10 at 13:28




2




2




Can you confirm that your code is not multithreaded (because instance is not atomic so that there could be a data race) ? Also, can you make the same test by using cout instead of your DEBUG_XXX, just to be sure that it's just a problem in the output ? FInally, could you show how you use your getInstance() ?
– Christophe
Nov 10 at 13:40




Can you confirm that your code is not multithreaded (because instance is not atomic so that there could be a data race) ? Also, can you make the same test by using cout instead of your DEBUG_XXX, just to be sure that it's just a problem in the output ? FInally, could you show how you use your getInstance() ?
– Christophe
Nov 10 at 13:40




1




1




Log* Log::instance = 0; is wrong! You should assign pointers with nullptr instead of just 0....
– Ruks
Nov 10 at 13:40






Log* Log::instance = 0; is wrong! You should assign pointers with nullptr instead of just 0....
– Ruks
Nov 10 at 13:40






1




1




I suspect that the pLog global is initialized after the code tries to access the instance. By using a global variable you are subverting the only thing that makes singletons better than a global variable - namely guaranteed construction before the first use.
– Michael Veksler
Nov 10 at 14:02




I suspect that the pLog global is initialized after the code tries to access the instance. By using a global variable you are subverting the only thing that makes singletons better than a global variable - namely guaranteed construction before the first use.
– Michael Veksler
Nov 10 at 14:02

















active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53239199%2fc-singleton-constructor-is-not-called%23new-answer', 'question_page');
}
);

Post as a guest





































active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes
















 

draft saved


draft discarded



















































 


draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53239199%2fc-singleton-constructor-is-not-called%23new-answer', 'question_page');
}
);

Post as a guest




















































































Popular posts from this blog

Full-time equivalent

Bicuculline

さくらももこ