Well, i'm using singleton in my own project. The most frequently used singleton implementation might be Meyer's singletion and that of using std::call_once or pthread_once. Both of them are thread safe for parallelized computing
//Meyer's singleton
class MySingleton{
public:
static MySingleton& getInstance(){
static MySingleton instance;
// volatile int dummy{};
return instance;
}
private:
MySingleton()= default;
~MySingleton()= default;
MySingleton(const MySingleton&)= delete;
MySingleton& operator=(const MySingleton&)= delete;
};
//with call_once
class MySingleton{
public:
static MySingleton& getInstance(){
std::call_once(initInstanceFlag, &MySingleton::initSingleton);
// volatile int dummy{};
return *instance;
}
private:
MySingleton()= default;
~MySingleton()= default;
MySingleton(const MySingleton&)= delete;
MySingleton& operator=(const MySingleton&)= delete;
static MySingleton* instance;
static std::once_flag initInstanceFlag;
static void initSingleton(){
instance= new MySingleton;
}
};
MySingleton* MySingleton::instance= nullptr;
std::once_flag MySingleton::initInstanceFlag;
Meyer's implimentation using local static variable to ensure thread safety and return the instance identity, while the latter one achieved by call_once and reture a pointer. In my experiment, the Meyer's implimentation sames a little bit faster. But most project using the call_once approach for the most basic singleton implimentation, althought some small component of the project using Meyer's implimentation. I just wondering is there any principle to follow, and what's the pros and cons of this two different implimentation?
The call_once version keeps a pointer to the instance and create it using new. Since no delete is ever called on the pointer, this solution poses some troubles if one needs sensible code to be run in the instance destructor. Apart from the annoying dangling pointer at process exit, one can consider using it if the instance destructor is just a default one like in your example.
Related
When using the Meyers singleton:
class Singleton
{
public:
static Singleton& instance()
{
static Singleton instance;
return instance;
}
void Hello()
{
std::cout <<"Hello!\n";
}
protected:
Singleton() = default;
~Singleton() {};
private:
Singleton(Singleton const&);
Singleton& operator=( Singleton const& );
};
You are able to call the instance as follow:
Singleton::instance().Hello();
or
Singleton& s = Singleton::instance();
s.Hello();
But I'm wondering if there is a way to block this:
Singleton::instance().instance();
How to avoid to call instance() as a method (with the .) and only support the static call with the :: ?
Is there a way to use static_assert, template enable_if or anything else?
First, I don't think this is a practical concern. Nobody is going to write Singleton::instance().instance().instance().Hello(). Or rather, if people are writing that on purpose, I think you have bigger problems. This is fine, as-is.
If you really want to prevent that, then you just have to move instance() outside of the class so it ceases to be a member function. There's nothing for you to assert or constrain, since you cannot tell if your static member function was called on an object or not (and you cannot overload a static member function with a non-static one taking the same argument list). Either you can write both Singleton::instance() and Singleton::instance().instance(), or neither.
Simplest is just:
class Singleton {
// ...
friend Singleton& make_singleton();
};
Singleton& make_singleton() {
static Singleton instance;
return instance;
}
Now it's just make_singleton().Hello(), and there's no other way to write that at all. This can be arbitrarily generalized by wrapping it in a singleton class template factory:
template <typename T>
struct SingletonFactory
static T& instance() {
static T instance;
return instance;
}
};
SingletonFactory<Singleton>::instance().Hello(); // ok
SingletonFactory<Singleton>::instance().instance().Hello(); // error
This question already has answers here:
How is Meyers' implementation of a Singleton actually a Singleton
(2 answers)
Closed 4 years ago.
A coworker and I were discussing about how to make a singleton and it turns out we're doing it differently.
My singleton :
class Singleton
{
public:
static Singleton* getInstance()
{
if(!instance) instance = new Singleton();
return instance;
}
~Singleton()
{
if(instance) delete instance;
}
private:
Singleton() {}
static Singleton* instance;
};
His singleton :
class Singleton
{
public:
static Singleton& getInstance()
{
static Singleton instance;
return instance;
}
private:
Singleton() {}
};
These examples are of course simplified for reading purposes. I like his solution because it is shorter and somehow more elegant, but something bugs me...
When his getInstance() method returns the instance, aren't we leaving the scope where it was declared and destorying it? How do you explain it's lifetime beyond the return?
You need to review storage classes in C++.
Any object declared as static (or extern) has static storage and gets destructed at the end of program in the reverse order of construction.
The order of construction of naked static objects is not deterministic and troublesome, especially in multi threading.
Function local static Objects(AKA Scott Meyer's singletons) OTH are ALAP constructed on first call to the owning function, and since C++11 in a magically thread safe manor(ie. no double construction).
I would add following declarations to your friend's class to make the singleton actually single:
class Singleton{
//...
Singleton(Singleton const&)=delete;
Singleton(Singleton&&)=delete;
auto& operator=(Singleton const&)=delete;
auto& operator=(Singleton &&)=delete;
};
I know that the singleton pattern is usually considered a bad design and hence discouraged, but this question concerns the implementation aspects, not the appropriateness of the singleton pattern.
Consider the following three implementations of a singleton in C++ using lazy initialization:
1: Using pointer, split between declaration and implementation
Singleton.hpp:
class Singleton {
public:
static Singleton* instance();
private:
Singleton() {}
static Singleton* singleton;
};
Singleton.cpp:
Singleton* Singleton::singleton = nullptr;
Singleton* Singleton::instance() {
if( nullptr == singleton ) {
singleton = new Singleton();
}
return singleton;
}
2: Using reference, split between declaration and implementation
Singleton.hpp:
class Singleton {
public:
static Singleton& instance();
private:
Singleton() {}
};
Singleton.cpp:
Singleton& Singleton::instance() {
static Singleton singleton;
return singleton;
}
3: Using reference, inline in declaration
Singleton.hpp:
class Singleton {
public:
static Singleton& instance() {
static Singleton singleton;
return singleton;
}
private:
Singleton() {}
}
I personally like and use the third version. But is there any good reason to prefer the first or the second version instead?
It is my understanding that in the third version there is an instance of the object for each translation unit that includes Singleton.hpp and then the linker picks a single one. Does this causes any side effect?
And are there any side effects using the third one in a shared library?
Bonus questions: which implementation is actually the "Meyer's singleton"?
The first one is not thread safe.
if( nullptr == singleton ) {
singleton = new Singleton();
}
It could happen that multiple threads could execute the allocation statement and create a memory leak.
The second and the third ones are thread-safe since C++11, because:
If multiple threads attempt to initialize the same static local
variable concurrently, the initialization occurs exactly once (similar
behavior can be obtained for arbitrary functions with std::call_once).
from here.
I'd prefer the third one because the inline optimisations are more likely.
Under these condition i wrote the next Singleton class :
1 - i want one and only one instance of the class to be present and to be accessible from the whole game engine .
2 - the Singleton is intensively used ( thousands times per frame) so i dont want to write an extra GetInstance() function , im trying to avoid any extra function call for performance
3 - one possibility is to let the GetInstance() be inlined like this :
inline Singleton* Singleton::GetInstance()
{
static Singleton * singleton = new Singleton();
return singleton;
}
but that will cause a reference problem , on each call there will be a new reference to the singleton , to fix that wrote in c++ :
class Singleton{
private:
static Singleton* singleton;
Singleton(){}
public:
static inline Singleton* GetInstance() // now can be inlined !
{
return singleton;
}
static void Init()
{
// ofc i have to check first if this function
// is active only once
if(singleton != nullptr)
{
delete singleton;
}
singleton = new Singleton();
}
~Singleton(){} // not virtual because this class can't be inherited
};
Singleton* Singleton::singleton = nullptr;
What are the possible problems i can face with this implementation ?
Your first implementation problem is a leak of the only new you call.
And the signature that force user to check pointer validity.
Your second implementation has even more problem as you require to use a 2-step initialization, and don't forbid copy/move/assignment.
Simply use Meyers' singleton:
class Singleton{
private:
Singleton() = default;
~Singleton() = default;
Singleton(const Singleton&) = delete;
Singleton operator&(const Singleton&) = delete;
public:
static Singleton& GetInstance()
{
static Singleton instance;
return instance;
}
};
In addition to #Jarod42's answer, I would like to point out that you could also implement a generic singleton by making template and use it in a CRTP class:
template<typename T>
class Singleton {
protected:
Singleton() = default;
~Singleton() = default;
Singleton(const Singleton&) = delete;
Singleton operator&(const Singleton&) = delete;
public:
static T& instance() {
static T instance;
return instance;
}
};
Then extend it:
struct MySingleton : Singleton<MySingleton> { /* ... */ };
Instead of a singleton, consider a namespace! Here's how I would do it:
// thing.h
namespace thing {
// public interface
int doSomething();
}
// thing.cpp
namespace thing {
namespace {
// private data and functions can go right here :-)
int private_data_ = 1234;
int doSomethingInternal() {
return private_data_ * 2;
}
}
// public interface
int doSomething() {
return doSomethingInternal();
}
}
Usage is simple like this:
int x = thing::doSomething();
No need for getInstance(), no memory leaks, and you can't accidentally make multiple instances.
but that will cause a reference problem , on each call there will be a new reference to the singleton
Incorrect; instead there will be a new class instance which is not the same as a reference. You will most likely end up leaking memory.
static Singleton* singleton;
Use a unique_ptr instead of a raw pointer. Compiler optimizations will devolve it into a raw pointer anyway, but now you're clearly telling the compiler what its lifespan should be.
class Singleton{
private :
static Singleton* singleton;
The default scope of a class is private; you don't need to explicity say private scope.
Singleton(){}
There is no need to provide an empty constructor when you have no other constructors in the class.
im trying to avoid any extra function call for performance
Compiled C++ will often inline such code anyway.
inline Singleton* GetInstance() // now can be inlined !
Make it static...?
~Singleton(){} // not virtual because this class can't be inherited
If your intent is to make it not inheritable, then add a final keyword to the class declaration. You can then remove the destructor.
I've got a Singleton implementation where I am not sure which drawbacks it contains. Could anybody tell me how good this implementation is?
template <class Child>
class Singleton {
public:
inline static Child& Instance() {
return Instance_;
}
Singleton(const Singleton&) = delete;
Singleton(Singleton&&) = delete;
Singleton& operator=(const Singleton&) = delete;
Singleton& operator=(Singleton&&) = delete;
protected:
Singleton() = default;
private:
static Child Instance_;
};
template <typename Child> Child Singleton<Child>::Instance_;
I know of a Singleton implementation by Scott Meyers that defines the static Instance_ inside the GetInstance() function.
inline static Child& Instance() {
static Child Instance_;
return Instance_;
}
But isn't there additional overhead involved, because it has to check every time the function is invoked whether Instance_ has already been initialized.
Your solution is prone to static initialization order fiasco.
A static class member is initialized together with all global static variables; before main(), in an unspecified order. If initialization of one static variable happens to reference another one, you get undefined behavior.
Using a static variable in function, however, gives you the special guarantee: the object will only be created when the function is executed for the first time. This means that you don't have to worry about initialization order (unless you create a cycle, obviously).
Regarding performance, the checking is implemented by compiler, so it's probably tuned extremely well. As always, if you're in doubt - benchmark.