![]() |
|
|
#1 (permalink) |
|
Member
Join Date: Feb 2009
Posts: 40
|
Serach for Robust Singleton Design Pattern in c++
Singleton Design Pattern :
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; } Now Can you say Is it complete design of Singleton..I hope more than 99% people will say NO !!! We have to take care about copy constructor .We should put copy constructor in private section also because any one can create a new object based on already created singleton object. Okay lets go ahead with step 2. 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; } Again problem will be now infinite time destructor will be called by line delete operator. 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; } } Now To make it complete singleton class some more addition is required. Like assignment operator is required or not...Offcourse it's required but it should be return same object. 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; } |
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|