Right or wrong, it's still trendy in some C++ circles to use the singleton pattern for defining a type that can only be instantiated at most once in an execution run. An example might be a god class that manages the top-level of your framework:
The constructor is private, so nobody can outright just instantiate a Kernel instance; in the meantime, the
Kernel::getInstance() function will give you access to the static member Kernel instance that's created once during static initialisation.
However, this can cause problems when you bring more static data into the mix. Consider the following example:
Because the Kernel instance is created before the Utility instance's constructor is invoked, this is safe.
But if we flip the static initialisation order of the two objects, then we're trying to use a data member inside Kernel that hasn't been initialised yet:
Worse, if your Utility and Kernel instances are defined in difference Translation Units (loosely corresponding to
.cpp source files in most projects), then their order of initialisation is completely non-guaranteed. It's pot luck as to whether your "simple" code will function at all.
It may seem contrived but this pattern has been seen in production code. To get around this issue when one static object depends on another static object, you can instead rely on the create-on-demand semantics of function-statics (an altogether different feature of the language):
In fact, in general it's best to try to avoid relying on static data members as these sorts of errors can go unnoticed for some time, and exerting control over C++'s static initialisation order is the sort of magic trickery best left to gremlins and hyperdimensional beings.
I'm having to add an addendum here to address a typical counter-response to my advice above.
It's been contested a few times that you can retain the use of the static member instance by using indirection, as in the following code. However, I've annotated the code to demonstrate how using dynamic allocation and a static member pointer does not solve this problem:
Remember: always prefer a function-static implementation object for singletons!