I have been reading a lot about Singletons, when they should and shouldn't be used, and how to implement them safely. I am writing in C++11, and have come across the Meyer's lazy initialized implementation of a singleton, as seen in this question.
This implementation is:
static Singleton& instance()
{
static Singleton s;
return s;
}
I understand how this is thread safe from other questions here on SO, but what I don't understand is how this is actually a singleton pattern. I have implemented singletons in other languages, and these always end up something like this example from Wikipedia:
public class SingletonDemo {
private static volatile SingletonDemo instance = null;
private SingletonDemo() { }
public static SingletonDemo getInstance() {
if (instance == null) {
synchronized (SingletonDemo .class){
if (instance == null) {
instance = new SingletonDemo ();
}
}
}
return instance;
}
}
When I look at this second example, it is very intuitive how this is a singleton, since the class holds a reference to one instance of itself, and only ever returns that instance. However, in the first example, I don't understand how this prevents there ever existing two instances of the object. So my questions are:
- How does the first implementation enforce a singleton pattern? I assume it has to do with the static keyword, but I am hoping that someone can explain to me in depth what is happening under the hood.
- Between these two implementation styles, is one preferable over the other? What are the pros and cons?
Thanks for any help,
This implementation is known as Meyers' Singleton. Scott Meyers says:
When you call
Singleton& s=Singleton::Instance()
first time the object is created and every next call toSingleton::Instance()
results with the same object being returned. Main issue:Another implementation is called the trusty leaky Singleton.
Two issues:
This is a singleton because
static
storage duration for a function local means that only one instance of that local exists in the program.Under the hood, this can very roughly be considered to be equivalent to the following C++98 (and might even be implemented vaguely like this by a compiler):
The thread safety bits make it get a bit more complicated, but it's essentially the same thing.
Looking at an actual implementation for C++11, there is a guard variable for each static (like the boolean above), which is also used for barriers and threads. Look at Clang's AMD64 output for:
The AMD64 assembly for
instance
from Ubuntu's Clang 3.0 on AMD64 at -O1 (courtesy of http://gcc.godbolt.org/ is:You can see that it references a global guard to see if initialization is required, uses
__cxa_guard_acquire
, tests the initialization again, and so on. Exactly in almost every way like version you posted from Wikipedia, except using AMD64 assembly and the symbols/layout specified in the Itanium ABI.Note that if you run that test you should give
Singleton
a non-trivial constructor so it's not a POD, otherwise the optimizer will realize that there's no point to doing all that guard/locking work.