Archive | Singleton RSS for this section

Getting Fancy With Patterns: the Singleton

A while back, a bunch of people that have probably been doing this stuff longer than you or I wrote a book called Design Patterns: Elements of Reusable Object-Oriented Software. This book contains details about a set of “patterns” that describe how things are commonly done, and how to do them properly. One such pattern is the Singleton.

The singleton is basically a class that there must only ever be one instance of. It has been debated whether or not a singleton should be used; a quick google search of anything singleton related will turn up a torrent of Stack Overflow threads with all the commenters berating the OP for daring to use a singleton. What is not up for debate is how to implement one.

A singleton enforces its singularity using a few techniques: The singleton contains a static instance of itself in the class definition, all its constructors are private, and it has a static public method that returns a pointer to its static instance. Below is a sample header of a singleton:

#ifndef SINGLETON_H #define SINGLETON_H namespace clt { namespace patterns { class singleton { public: static singleton * get_instance(); static void destroy_instance(); ~singleton(); private: static singleton * instance; singleton(); singleton(const singleton& orig); singleton& operator=(const singleton& orig); }; } } #endif /* SINGLETON_H */

First, you’ll notice that all of our constructors, and operator= are private. Secondly, you’ll see the two static public methods: get_instance() and destroy_instance(). These two methods handle creation and deletion of the singleton. Also, I have a destructor. It is very important that you do not attempt to call delete instance from within the destructor! If you do this, you will get an infinite loop. However, you should still put all the rest of your destruction logic in the destructor. Below I’ll go over the implementation of these methods:

#include "singleton.h" using namespace clt::patterns; singleton * singleton::instance = 0; singleton * singleton::get_instance() { if (instance == 0) { instance = new singleton(); } return instance; } void singleton::destroy_instance() { delete instance; instance = 0; }

You may be wondering about the third line: singleton * singleton::instance = 0. This is required to for the initialization check in get_instance. If this line is not here to initialize it to 0, you’ll get compiliation errors. Unlike a normal class, you can’t put this in the constructor because this value is needed before construction.

The method get_instance() does two things. First, it checks to see that instance is not a null pointer. If it is, calls new singleton and assigns the resulting singleton to instance. Next it returns the instance pointer.

destroy_instance() is quite straightforward. First, it calls delete instance. next, it resets instance to 0 so that the singleton can be recreated by a call to get_instance().

…and that’s all there is to it. You now have all the tools you need to create your own singleton. Global variables will never be the same…

%d bloggers like this: