Sunday, September 4, 2011

Simple Singleton explanation

Hi there people,

I just spent one day trying to figure out why my C++ destruction sequence was creating a resource leak... This morning I noticed it came from one of my Singleton, the one behaving as my database manager.

So people, please be careful when using the Singleton Pattern, esp. when you access resources such as connections, or files.

Here is the thing:

In most cases, you can create a static class member pointing to the instance of your Singleton. This way is really easy to use but generates leak because the destructor is not clearly called. In fact, the memory de-allocation will be done by the OS once you exit your application. Here is the usual code.

// singleton.h
class Singleton
{
public:
    static Singleton* getInstance();
    // Other functions if needed
private:
    Singleton();
    ~Singleton();
    static Singleton* _singletonInstance;
};

// singleton.cpp
#include "singleton.h"

Singleton *Singleton::_singletonInstance = NULL;

Singleton*
Singleton::getInstance()
{
    if(!_singletonInstance){
        _singletonInstance = new Singleton();
    }
    return _singletonInstance;
}

Singleton::Singleton()
{
    // Do what you have to do
}

Singleton::~Singleton()
{
    // Do what you have to do
}

Note: you can see I'm using the lazy initialization to create the instance of my Singleton.

Anyway, this is a very easy and convenient way to have a global and unique instance... Of course, this assume that you do not really need to care about your singleton anymore.

However, if you really need the destructor to be called (e.g. to close a stream) then, it's better to have a simple static variable (no need to check its existence either, it will be created once and for all at the beginning of the application). In this case you can be sure that the destructor will be called. Here is the code:

// singleton.h
class Singleton
{
public:
    static Singleton* getInstance();
    // Other functions if needed
private:
    Singleton();
    ~Singleton();
    // No static class member here !
};

// singleton.cpp
#include "singleton.h"

Singleton*
Singleton::getInstance()
{
    static Singleton _singletonInstance;
    return &_singletonInstance;
}

Singleton::Singleton()
{
    // Do what you have to do
}

Singleton::~Singleton()
{
    // Do what you have to do
}

Of course, you can also do something like this if you want:

Singleton*
Singleton::getInstance()
{
    Singleton* pSingleton = NULL
    static Singleton _singletonInstance;
    pSingleton = &_singletonInstance
    return pSingleton;
}

Anyhow, this second way is much better in the case of a destruction sequence which needs to be clear. In fact, this solved my memory leak problem since with this second version of the Singleton, my destructor was correctly called and the connection to the database was correctly closed.

For your interest, this 2nd case is also called the Meyers' implementation of the Singleton, whereas the 1st one is the GoF implementation.

I hope it can be useful for some of you.

No comments:

Post a Comment