I am new to C/C++
I tried to implement singleton-pattern.
why doesn't following code not compile. In javascript there is no problem implementing the singleton pattern in a similar fashion. (https://addyosmani.com/resources/essentialjsdesignpatterns/book/#singletonpatternjavascript)
I thought that when I declare the pointer *singleton_instance
static
it could be accessed by the static method. But G++ gives the error
singleton_pattern_nullptr.cpp:12:20: warning: ‘constexpr’ needed for in-class initialization of static data member ‘Grammar* Grammar::singleton_instance’ of non-integral type [-fpermissive]
12 | static Grammar *singleton_instance = NULL;
But even with
#include <iostream>
#include <stdio.h>
#define NULL nullptr
class Grammar {
protected:
Grammar() {};
Grammar(const Grammar&) = delete;
Grammar& operator=(const Grammar&) = delete;
static Grammar *singleton_instance = NULL;
public:
Grammar& getInstance();
};
static Grammar& Grammar::getInstance() {
if(singleton_instance == NULL) {
// no star with new
singleton_instance = new Grammar();
}
return *singleton_instance;
}
int main(int argc, char* argv[]) {
Grammar *grammar;
grammar = Grammar::getInstance();
return 0;
}
Now when I define
static constexpr Grammar *singleton_instance = NULL;
g++ spawns the error message...
singleton_pattern_nullptr.cpp:23:23: error: assignment of read-only variable ‘Grammar::singleton_instance’
23 | singleton_instance = new Grammar();
and still ...
singleton_pattern_nullptr.cpp:33:34: error: cannot call member function ‘Grammar& Grammar::getInstance()’ without object
33 | grammar = Grammar::getInstance();
I thought I could make it mutable
but in this thread (static mutable member variables in C++?) I read that it shouldn't be necessary for a static member variable to be specified mutable
in order to be that (mutable) because this should already be the case anyway.
So please tell me where my error is and if an implementation of a singleton like I thought of above (see javascript example) is possible in C++ or not.
Thanks
EDIT:
After having acknowledged the present answers so far, I cannot tell what I am doing wrong still. Please tell me how I can change define the pointer *singleton_instance
and Grammar::getInstance()
such that I can manipulate the pointer according to the idea, if possible. I now have frustranely declared both static, and declared *singleton_instance
with the modifier constexpr
according to the error message by g++.
It can't be that hard, can it?
Another example: https://developer-blog.net/singleton-design-pattern-in-c/
Thanks
EDIT 2:
Thanks to M47 for posting a working "Meyers Singleton" (as user idclev 463035818 annotes)
But although I set the flag -std=c++17
the compiler still responds with the warnings
**singleton_pattern.h:9:12:** warning: inline variables are only available with ‘-std=c++17’ or ‘-std=gnu++17’
9 | static inline Grammar *singleton_instance = nullptr;
But allow me three (two?) more comprehension questions regarding c++ please.
1 - In the header file, the method is declared as static inline
static inline Grammar *singleton_instance = nullptr;
In the definition however, you pass on these "modifiers" (?).
Or is either static
or both static inline
implicit in the definition via the namespace/class-operator ::
? I think I have read something like that somewhere.
Grammar& Grammar::getInstance()
If this is not so, then I know there are threads on divergent modifiers in header file declarations and cpp file definitions. Could you give me a prompt?
Last but not least (minor problem) I get the warning
warning: variable ‘grammar’ set but not used [-Wunused-but-set-variable]
Thank you very much for showing me how I can get the pointer version of the singleton pattern to work ! kudos!