Background
Normally most of software Engineer uses singleton design pattern in daily coding life. It's very simple , vast uses but still i saw in many softwares which is not handled proper in C++ based products/projects. One thing more you can'nt design singleton as perfectly behaved singleton. But here approch and solution for how to make perfact singleton class in C++.
Why Singleton: To maintain object as single instance which is used by more than one user.
Details & Step by Step Improvement
Step 1: In first sight, singleton can be create as
Code:
class Singleton
{
public:
static Singleton * CreateSingleton();
private:
static Singleton *instSingleton_mp;
Singleton(){ ; }
};
//Definition
Singleton* Singleton::InstSingleton_mp = NULL;
Singleton* Singleton::CreateSingleton()
{
if (NULL = = InstSingleton_mp)
{
InstSingleton_mp = new Singleton();
}
return InstSingleton_mp;
}
Step 2: Adding Copy Constructor in private section
Code:
class Singleton
{
public:
static Singleton * CreateSingleton();
private:
static Singleton *instSingleton_mp;
Singleton(){ ; }
Singleton(const Singleton &) { ; }
};
//Definition
Singleton* Singleton::InstSingleton_mp = NULL;
Singleton* Singleton::CreateSingleton()
{
if (NULL = = InstSingleton_mp)
{
InstSingleton_mp = new Singleton();
}
return InstSingleton_mp;
}
Now Again Some people (Now i hope 95%) will say it's not complete design, we should take of memory management. Okay Now we will go for that.
Step 3: Adding memory management code
Code:
class Singleton
{
public:
static Singleton * CreateSingleton();
~Singleton();
private:
static Singleton *instSingleton_mp;
Singleton(){ ; }
Singleton(const Singleton &) { ; }
};
//Definition
Singleton* Singleton :: InstSingleton_mp = NULL;
Singleton* Singleton :: CreateSingleton()
{
if (NULL = = InstSingleton_mp)
{
InstSingleton_mp = new Singleton();
}
return InstSingleton_mp;
}
Singleton :: ~ Singleton()
{
detele InstSingleton_mp;
}
Okay It can be done by little bit changes.
Step 4: Adding memory management code ( Continued )
Code:
class Singleton
{
public:
static Singleton * CreateSingleton();
~Singleton();
void DestroyMe();
private:
static Singleton *instSingleton_mp;
Singleton(){ ; }
Singleton(const Singleton &) { ; }
};
//Definition
Singleton* Singleton :: InstSingleton_mp = NULL;
Singleton* Singleton :: CreateSingleton()
{
if (NULL = = InstSingleton_mp)
{
InstSingleton_mp = new Singleton();
}
return InstSingleton_mp;
}
Singleton :: DestroyMe()
{
if( NULL ! = InstSingleton_mp )
{
detele InstSingleton_mp;
InstSingleton_mp=NULL;
}
}
Now I hope 90% people will say again it has problem, suppose lot of users using this application then ... Suppose X guy uses this object and release it and other guy Y still wants to use this object then problem.....Okay lets see in next step.
Step 5: Introducing reference counts (In our software a class is available for it)
Code:
class Singleton
{
public:
static Singleton * CreateSingleton();
~Singleton();
void DestroyMe();
private:
static Singleton *instSingleton_mp;
static int refCount;
Singleton(){ ; }
Singleton(const Singleton &) { ; }
};
//Definition
Singleton* Singleton :: InstSingleton_mp = NULL;
int Singleton :: refCount = 0;
Singleton* Singleton :: CreateSingleton()
{
if (NULL = = InstSingleton_mp)
{
InstSingleton_mp = new Singleton();
++refCount;
}
return InstSingleton_mp;
}
Singleton :: DestroyMe()
{
if( NULL ! = InstSingleton_mp && 0 = = refCount)
{
detele InstSingleton_mp;
--refCount;
InstSingleton_mp=NULL;
}
}
Now hope people will say it's perfect solution. But still i hope 80% people will say it has problem ...Suppose One user calling DestroyMe() function more than one times, lets say five times then no probs for a while( on that time refCount will be -4 ) but problem will be raised when next user is calling createSingleton() (refCount will be -3) and calking DestroyMe() in which destructor itself will not be called. A liitle bit changes can be done.
Code:
Singleton :: DestroyMe()
{
if( NULL ! = InstSingleton_mp && 0 = = refCount)
{
detele InstSingleton_mp;
if(0 < refCount)
--refCount;
InstSingleton_mp=NULL;
}
}
One more have putted destructor in public better if we will put in private because more constructor which is not in private can be putted in public section. To avoid this situation better if you put destructor in private section.
Coplete design of singleton is as:
Code:
class Singleton
{
public:
static Singleton * CreateSingleton();
void DestroyMe();
Singleton& operator= (const Singleton& );
private:
static Singleton *instSingleton_mp;
static int refCount;
Singleton(){ ; }
Singleton(const Singleton &) { ; }
~Singleton();
};
//Definition
Singleton* Singleton :: InstSingleton_mp = NULL;
int Singleton :: refCount = 0;
Singleton* Singleton :: CreateSingleton()
{
if (NULL = = InstSingleton_mp)
{
InstSingleton_mp = new Singleton();
++refCount;
}
return InstSingleton_mp;
}
Singleton :: DestroyMe()
{
if( NULL ! = InstSingleton_mp && 0 = = refCount)
{
detele InstSingleton_mp;
if(0 < refCount)
--refCount;
InstSingleton_mp=NULL;
}
}
Singleton& operator= (const Singleton& obj)
{
return *this;
}
References
1. GoF http://www.vincehuston.org/dp/
2. http://hitechi.19.forumer.com/viewtopic.php?t=41
3. Idea for Style of writing this article is taken from code guru.
Note: Code written in this article is morally as designed purpose so dont expect it's runnable code. You may get compilation error.



