Re: Singleton --- Just Look and give Suggestion's
On Mar 5, 5:16 pm, Pallav singh <singh.pal...@gmail.com> wrote:
1. its not executing display() properly ....just look to it
2. Suggest effective way to write MUTEX class at User level
#include <iostream.h>
using namespace std;
template<typename TYPE>
class Singleton
{
private :
Singleton() { cout<<" constructor Invoked "<< endl; }
~Singleton() { cout<<" Destructor Invoked "<<endl; }
Singleton(const Singleton<TYPE> & a)
{ cout<<" Copy Constructor Invoked "<<endl; }
const Singleton<TYPE> & operator = (const Singleton<TYPE> &);
A singleton should not support copy, and since there can never
be more than one of them, there's no point in supporting
assignment, either.
static TYPE * instance;
static volatile long Flag; // Flag is volatile.
What on earth for?
public :
static TYPE * GetInstance( void )
{
if( Flag == 0 )
{
// TO BE DONE Guard<Mutex> acquire();
if( Flag == 0 )
{
if( instance != NULL)
{ try
{ instance = new TYPE();}
catch(...)
{ cout <<"Creation of Object failed
"<<endl; }
}
cout<<" Instance Created Successfully \n";
Flag = 1;
// Mutex.release();
}
return instance;
}
else
{
cout<<" Returning the Already Created Instance \n";
return instance;
}
}
};
The comments about mutexes above are misleading; even with the
mutexes, the code isn't thread safe. Which generally isn't a
problem; just ensure that instance() is called at least once
before threading starts. Of course, the above can be written
much simpler:
static Type& instance()
{
if ( ourInstance == NULL ) {
ourInstance = new Type ;
}
return *ourInstance ;
}
This is far simpler, and works just as well as what you have
written.
template<typename TYPE>
TYPE * Singleton<TYPE>::instance = 0 ;
If I want to use the code in a multithreaded environment, I'd
write:
template< typename Type >
Type* Singleton< Type >::ourInstance
= & Singleton< Type >::instance() ;
This will ensure that instance() is called at least once before
entering main (and thus, normally, before threads are started).
template<typename TYPE>
volatile long Singleton<TYPE>::Flag = 0;
As mentionned above, the variable isn't needed, and the volatile
doesn't affect anything. And using a long for something which
can only take two values, 0 and 1, is a bit strange as well.
class A
{
public :
int i,j;
A(int i = 1 , int j = 1):i(i),j(i){}
void display()
{ cout<<" value of i "<< i <<" value of j "<< j <<endl; }
};
int main()
{
A * obj1 = Singleton<A>::GetInstance();
A * obj2 = Singleton<A>::GetInstance();
A * obj3 = Singleton<A>::GetInstance();
obj1->display();
//obj2->display();
//obj3->display();
// To check if it call destructor of Object
delete obj1;
delete obj2;
delete obj3;
}
What's the relationship of A to Singleton? A isn't a singleton,
so delete of an A* is perfectly fine. A is NOT a singleton.
And since obj1, obj2 and obj3 all point to the same object, the
second and third deletes are undefined behavior.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34