you don't need to introduce a pointless class called "Singleton" if all you want is to enforce initialization order, though.
(I don't think there are any "pros", Singleton is always an anti-pattern)
I don't think I've ever needed to create a singleton, and most of the time I've seen them used, there's been a better solution.
I saw a singleton once called globals. It contains all the logically global data for the program. It appeared to me that someone just decided that "globals are always bad" so he/she wrapped them up in a bunch of pointless machinery. Sometimes you really do need globals. Just look at cout and cerr.
Other times I've seen:
1 2 3 4 5 6 7
class Singleton;
int i;
string str;
// etc;
// bunch of machinery to make this a singleton.
};
It would have been much simpler to just make the data static members or use a namespace. However, see the comments by Peter87 and Cubbi about static initialization.
The whole GoF to me reads like "workarounds for the lack of features in early Java", but even there, Singleton is not the only way to introduce a hidden dependency on global state: there are static classes, too.
Talking about preventing the "static initialization order fiasco" without using Singletons, isn't the example essentially still a singleton?
1 2 3 4 5
Fred& x()
{
static Fred* ans = new Fred();
return *ans;
}
I mean it's definitely simpler syntactically than the usual way of making Fred a "real" singleton, but what makes it functionally better? (Edit: To partially answer my own question, I guess it would be that it allows you to still make your own Fred object if you really need an isolated version of it in another place.)
The whole GoF to me reads like "workarounds for the lack of features in early Java",
See and I've heard that exact line, except replace "early Java" with "C++". (I haven't actually read GoF, though...)
Why call 'new' there? static Fred ans; return ans; is enough in most simple cases if you need a lazy-initialized global.
except replace "early Java" with "C++"
Well, it's true that it used "C++" in its examples, horrifying pre-standard "C++" from the dark days of extreme OOP craze. Java scooped up all that garbage, at least initially.