In the second part of this series, Lets look at a simple singleton implementation and see how these questions affect the implementation.
(a) There is no guarantee that User of the class cannot create another instance of the class. So technically this is not a singleton.
(b) User can derive from this class. Usually not a good idea for singletons.
(c) Single instance is implemented using file static object. The sequence of static objects is decided by the compiler. Hence if other static objects depend on Singleton instance of FooSingleton, you have a problem. It may happen that g_fooSingleton is not initialzed yet.
Not a well behaved implementation.
Lets see how to improve on this. First lets make the constructor of the FooSingleton private. This will take care of (a) and (b). Problem however is then you cannot create file static 'g_fooSingleton'. It has to be implemented differently.
1. GetFooObj is returning a pointer. What happens if user deletes this pointer by mistake ? The FooSinglton object will NOT know that the pointer is already deleted.
2. Exactly this singleton instance of FooSingleton is going to be destroyed ? Since m_pFoo is a pointer, its destructor will not get called automatically. That could be a problem.
The User (developer) has to manange the destruction of Singleton object and he needs to be really careful in using the class (.e.g don't keep copy of the pointer to FooSingleton, don't delete the pointer to FooSingleton etc). Not a well behaved implementation.
How to improve on this is part of next installment of this series :-)
The problems with this codeclass FooSingleton{ public : FooSingleton(void); ~FooSingleton(void); static FooSingleton* GetFooObj(void); private : int m_var; }; static FooSingleton g_fooSingleton; FooSingleton* FooSingleton::GetFooObj(void) { return(&g_fooSingleton); }
(a) There is no guarantee that User of the class cannot create another instance of the class. So technically this is not a singleton.
(b) User can derive from this class. Usually not a good idea for singletons.
(c) Single instance is implemented using file static object. The sequence of static objects is decided by the compiler. Hence if other static objects depend on Singleton instance of FooSingleton, you have a problem. It may happen that g_fooSingleton is not initialzed yet.
Not a well behaved implementation.
Lets see how to improve on this. First lets make the constructor of the FooSingleton private. This will take care of (a) and (b). Problem however is then you cannot create file static 'g_fooSingleton'. It has to be implemented differently.
First call to GetFooObj will create the Singleton instance, subsequence calls will return the same instance. There are still problems with this implementation.class FooSingleton { public: ~FooSingleton(void); static FooSingleton* GetFooObj(void); private : FooSingleton(void); private : int m_var; static FooSingleton* m_pFoo; }; FooSingleton* FooSingleton::m_pFoo= NULL; FooSingleton* FooSingleton::GetFooObj(void) { if( m_pFoo == NULL) m_pFoo = new FooSingleton(); return(m_pFoo); }
1. GetFooObj is returning a pointer. What happens if user deletes this pointer by mistake ? The FooSinglton object will NOT know that the pointer is already deleted.
2. Exactly this singleton instance of FooSingleton is going to be destroyed ? Since m_pFoo is a pointer, its destructor will not get called automatically. That could be a problem.
The User (developer) has to manange the destruction of Singleton object and he needs to be really careful in using the class (.e.g don't keep copy of the pointer to FooSingleton, don't delete the pointer to FooSingleton etc). Not a well behaved implementation.
How to improve on this is part of next installment of this series :-)