Quite a horrible example. Let's have a look at the details:
static Singleton* Instance();
The function should return Singleton&
, not Singleton*
.
protected:
Singleton();
protected
only makes sense for classes designed to be derived from. It does not make a lot of sense to derive from a Singleton. At best, it's an exotic special case. A Singleton constructor is typically private
.
Singleton* Singleton::_instance = 0;
Since C++11, nullptr
should be used for null pointers.
Singleton* Singleton::Instance() {
if (_instance == 0) {
_instance = new Singleton;
}
return _instance;
}
Not thread-safe. Let's say 3 threads (A, B and C) call Instance()
at the same time. All three of them concurrently reach if (_instance == 0)
for the first time. The condition is thus true for all of them, so all of them enter into the if
block - resulting in three instances being created!
I'm pretty sure it comes from this line here
Singleton* Singleton::_instance = 0;
But I have no idea what that line actually does or how it works.
It initialises the static
_instance
member variable of the Singleton
class. static
in this context means that the variable exists independently of any Singleton
instances, so you can access it in a static
member function like Instance()
.
Since C++11, a thread-safe way to implement Singletons is to instead use a static
local variable:
Singleton& Singleton::Instance() {
static Singleton instance;
return instance;
}
The technique has existed for a long time, but it's thread-safe only since C++11 because only the C++11 standard officially acknowledged the existence of multi-threading, including certain guarantees for local static
variables.
The drawback of this technique is that you can run into order-of-destruction issues if you have multiple Singleton classes and the destructor of one accesses another Singleton.
There are ways around this issue, but I will not go into further detail here, because now that you have learnt a few things about Singleton - Do not use the pattern.
Most programmers these days have learnt the hard way that Singletons are just global variables in disguise and should be used almost as rarely. They create global dependencies all over your code, making testing and modularisation harder or impossible, and are hard to implement correctly and safely. Singleton is the number one black sheep in the Gang of Four book.
By the way, look what Microsoft themselves are saying at the top of the page you refer to:
This content is outdated and is no longer being maintained. It is
provided as a courtesy for individuals who are still using these
technologies.