I have implemented two methods of how I think a Singleton class should be implemented, I just want the opinion of programmers to which one is the best method to use.
Each of the methods uses these classes:
class Animal {
public:
virtual void speak() const = 0;
};
class Dog {
virtual void speak() { cout << "Woof!!"; }
};
First method:
class AnimalFactory {
public:
static Animal* CreateInstance(int theTypeOfAnimal);
private:
AnimalFactory() { };
static int count; // this will be used to count the number of objects created
static int maxCount; // this is the max count allowed.
};
int AnimalFactory::count = 0;
int AnimalFactory::maxCount = 1;
Animal* AnimalFactory::CreateInstance(int theTypeOfAnimal)
{
Animal* pAnimal = NULL;
if(pAnimal != NULL)
{
return pAnimal;
}
switch(theTypeOfAnimal)
{
case 0:
pAnimal = new Dog();
count++;
break;
case 1:
pAnimal = new Cat();
count++;
break;
case 2:
pAnimal = new Spider();
count++;
break;
default:
cout << "Not known option";
}
return pAnimal;
}
Second Method:
template<typename classType>
class Singleton {
public:
classType& instance()
{
static classType object;
return object;
}
};
Any opinion would be grateful, thanks :)!
The first code snippet fails to implement a singleton because
AnimalFactory::CreateInstancefails to check the instance count that it maintains.The second code snippet,
when done properly, is called a Meyers’ singleton, after Scott Meyers.
The code as given would work but yields awkward usage. To avoid having to instantiate
Singleton, theinstancemethod should be declaredstatic. Also, the requirement onclassTypeclasses that they should only instantiable bySingleton, should be documented, e.g. as a comment with an example.Others have already warned you against using singletons, but let me also do that.
Singletons have their uses, such as ensuring that e.g. a Windows API “window class” is only created once, but mainly they’re abused as global-variables-in-disguise. One problem with global variables, namely that you don’t know when a global variable has been initialized (in C++ programming known as the static initialization order fiasco), is avoided by singletons. However, the main problem, that they serve as spaghetti communication systems, routing chaos-inducing information in untraceable ways between places you would never suspect, is still there.
So, don’t.
But if you at some time find that you absolutely need singletons, e.g. for a logging facility, then please do read up on the discussion of singletons in Andrei Alexandrescu’s “Modern C++ Design”, and then get hold of the Loki library and let it do the job for you.