Introduction
Let’s see what makes a professional programmer different from a beginner? Beginners start with a trial and error method to solve a problem, and most often the solution is far from perfect and it takes them to the later problems. In the same situation, a professional doesn’t try to invent a new solution, but instead he tries to match the situation with an already existing pattern. Design Patterns are a set of most common problems which a programmer faces, in software design. In these series of articles we are going to explain some of the basic Design Patterns, We also try to show you an effective implementation of these Patterns in C++; however you can also extend the implementation to other programming languages.
Singleton
There are a lot of situations which you need to make a unique instance of an object and make it accessible for the other parts of the code. For example assume you have a Logger class and you want all the subsystems to log their activities with a single object of the Logger class. Also duplication of the instance can cause unwanted results and you don’t want to allow creating more than a single instance of the class. So what’s the solution?
An easy way is to use a global object as an extern symbol.
extern Logger log;
void func()
{
log->Print(“I have a lot to learn!”);
}
In this way you can rather easily access the shared object with a declaration of the object. But it hasn’t solved the problem completely yet because there is no way to ensure that no body make another instance of the logger class, even that line of comment can’t help you because a lot of programmers don’t take advices, you must make them respect the rules!
So what? What is the solution?
Fortunately this situation matches a well known Design Pattern which we already have a solution for and it is the “Singleton”. A nice way to implement a Singleton can be done using C++ templates.
template <class T>
class Singleton
{
public:
static T *GetInstance()
{
static T instance;
return &instance;
}
};
Singleton class stores a pointer to the child class in a static variable. GetInstance() is also a static function which makes the object accessible for all the code and handles creating the object internally and the constructor is defined as protected so nobody can try to build an instance of the object. Here is how to use this class for our logger example:
class Logger: public Singleton<Logger>
{
public:
void Print(char *str,...);
protected:
Logger();
};
Logger::GetInstance()->Print("Now I feel better!");
Another implementation can be done using define macro:
#define DECLARE_SINGLETON(CLASS) public:static CLASS *GetInstance(){ static CLASS instance; return &instance; }
class Logger
{
DECLARE_SINGLETON(Logger);
public:
void Print(char *str,...);
protected:
Logger()
};
There are some other good implementations of Singleton which you can find around the net and you can also write your own implementation but the concept is the same and next time you see the Pattern it’s so easy for you to find the optimal solution. OK, here we reached the end of the line! If you have comments or questions let me know by writing to vkazemi {at} gmail.com and make sure to check my web site for the updates: http://www.gameprogrammer.org/