(This questions assumes that a global + unique object is the goal. I would like to clarify that this does not mean it is asking about or advocating the if/why/when of using/not-using singletons or globals.)
I am wondering if there's a technicality about C++ that I'm missing, so my question is:
Is a namespace implementation of the singleton pattern in C++ valid? And if so, is there a reason why it is not often suggested as the better approach?
From Google's style guidelines, we see namespace non-member functions recommended over static member function, but only when not sharing static data:
"Rather than creating classes only to group static member functions which do not share static data, use namespaces instead."
Why shy away from letting non-member functions share static data, declared in an unnamed namespace? Is there something wrong about this that explains why namespaces aren't generally suggested as a better alternative to writing a singleton class in C++?
Because I can't find recommendations of the namespace approach, but it is very easy to find the class approach despite C++ not enforcing the use of classes:
Can any one provide me a sample of Singleton in c++?
Singleton instance declared as static variable of GetInstance method
http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf
Singleton: How should it be used
Using a named namespace with an unnamed namespace in its source file:
- You can have 'state' via static data
- You can gain the extra privacy of putting things in an unnamed namespace
- You can still control the construction order of its static objects by using static pointers, and constructing from function calls.
- You don't need to implement a singleton class
Edit - Example of namespace approach I was thinking:
SingleThing.h:
namespace single_thing // The singleton (if this is actually valid)
{
void GrowSomeCats(int amount); // Typical setter
int GetNumCats(); // Typical getter
}
SingleThing.cpp:
#include "Balloon.h"
namespace // Acting like private members and functions
{
int numCats = 4; // POD
Balloon* wilson = NULL; // Not POD (and not a singleton)
// Contrived 'private' function
bool CanGrowCats()
{ return wilson && wilson->LikesCats(); }
// Contrived excuse to instantiate non-POD 'members'
void RandomlyCreateOtherObjects()
{
if (!wilson /* && someRandomiserImTooLazyToType()*/ )
wilson = new Balloon();
}
}
namespace single_thing // 'Public' functions
{
void GrowSomeCats(int amount)
{
RandomlyCreateOtherObjects();
if (CanGrowCats())
numCats += amount;
}
GetNumCats()
{ return numCats; }
}