 |
|
 |
As I understood, you actually don't need to create any flags. Instead you can compare to NULL the instance of the class Singleton.
|
|
|
|
 |
|
 |
I think it's pretty good. Certainly simple and straightforward.
Because the class recognizes whether or not a class pointer is NULL or not, you cannot delete the class pointer after each use because when you call the class getInstance again, a new instance will be instantiated and the class will no longer function as a Singleton. So simply delete the class pointer once, after you're done using it.
Singleton *sc1,*sc2, *sc3, *sc4, *sc5;
sc1 = NULL; sc2 = NULL; sc3 = NULL; sc4 = NULL; sc5 = NULL;
sc1 = Singleton::getInstance(); sc1->method(); //delete sc1; sc1 = NULL;
sc2 = Singleton::getInstance(); sc2->method(); //delete sc2; sc2 = NULL;
sc3 = Singleton::getInstance(); sc3->method(); //delete sc3; sc3 = NULL;
sc4 = Singleton::getInstance(); sc4->method(); //delete sc4; sc4 = NULL;
sc5 = Singleton::getInstance(); sc5->method(); delete sc5; sc5 = NULL;
No leak!! Only one instance constructed.
Not sure about how to make it thread safe. Any ideas how to add a critical section ?
|
|
|
|
 |
|
 |
1. It is not thread-safe solution.
2. You should think about protected destructor and memory clean up.
|
|
|
|
 |
|
|
 |
|
|
 |
|
 |
Why storing a bool var and use that when you can use the pointer to the singleton for checking?
class Singleton
{
private:
static Singleton *single;
Singleton()
{
//private constructor
}
public:
static Singleton* getInstance();
void method();
};
Singleton* Singleton::single = NULL;
Singleton* Singleton::getInstance()
{
if(! single)
{
single = new Singleton();
}
return single;
}
void Singleton::method()
{
cout << "Method of the singleton class" << endl;
}
|
|
|
|
 |
|
 |
... you must create a singleton without using static variables ?
Any ideas?
|
|
|
|
 |
|
 |
no its really not possible without having a static refernec variable to create Singletone pattern
|
|
|
|
 |
|
 |
file: Single.cpp
#include "Single.h"
bool CSingle::m_bIsCreated = false;
file: Single.h
class CSingle
{
static bool m_bIsCreated;
CSingle(const CSingle& c){};
public:
CSingle()
{
if (!m_bIsCreated)
{
m_bIsCreated = true;
}
else
{
//Sound alarm
//assert(true);
throw(0);
}
};
virtual ~CSingle()
{
m_bIsCreated = false;
};
};
|
|
|
|
 |
|
 |
Why not the following?
class SimplerSingleton
{
public:
SimplerSingleton(){};
void method()
{
cout << "Method of the SimplerSingleton class 0x" << hex << this << endl;
}
};
static SimplerSingleton _gSingleton;
int main(int argc, char* argv[])
{
_gSingleton.method();
_gSingleton.method();
return 0;
}
Sincerely,
-Ron
|
|
|
|
 |
|
 |
Because you can have several instances of your SimplerSingleton class
for example this would work:
SimplerSingleton _gSingleton1;
SimplerSingleton _gSingleton2;
the key idea is to prevent the creation of more than one instance.
Alex-
|
|
|
|
 |
|
 |
Singletone is about creation of single object in code not shared object one shud have control over creation of the object hence singletone always has a creator method
|
|
|
|
 |
|
 |
you know what is the mean of Singleton Class?
Regards,
Srinivas
|
|
|
|
 |
|
 |
Let's make a few changes to the source code presented in the article. (Singleton::method - replace the method body with the line below) cout << "Method of the singleton class - object <" << this << ">" << endl; (main method - add the following lines just before the return statement) Singleton* sc3 = &Singleton( *sc1 ); sc3 -> method(); Now, compiling and running the program - by the way, I'm using Visual C++ 6.0 on a NT 4.0 SP 4 machine - we get the following output: Method of the singleton class - object <00300EC0> Method of the singleton class - object <00300EC0> Method of the singleton class - object <0012FF70> I think this means the singleton class is not really a singleton. However, we could make the copy constructor inaccessible by declaring it private: (class Singleton - add the following line just after the constructor) Singleton(const Singleton&); Now, when we try to build the executable, the compiler complains saying that we 'cannot access private member declared in class'. At last, always to prevent a user of the Singleton class from making copies of a Singleton object, we could declare the assignement operator private as well: (class Singleton - add the following line just after the copy constructor) Singleton& operator=(const Singleton&); Regards.
|
|
|
|
 |
|
 |
ThumbUp wrote:
At last, always to prevent a user of the Singleton class from making copies of a Singleton object, we could declare the assignement operator private as well:
(class Singleton - add the following line just after the copy constructor)
Singleton& operator=(const Singleton&);
I belive here you're wrong. If you have the copy constructor and the default constructor private there is no way you can do an attrib like that because you don't have an object to copy to. Also, when you do code like:
Singleton s = *(Singleton::instance());
it's the copy constructor that's called, not the equal operator. Otherwise, very good point regarding the copy constructor to be made private also. The equal operator (and allmost all other operators) are called on already instantiated objects.
Cheers
|
|
|
|
 |
|
 |
lol
Boys one thing that is missing in the code and that is every singletone class shud have a private contructor so that the code u r trying will never get executed .
|
|
|
|
 |
|
 |
Hi there,
This implementation is pretty good for singlethreaded or appartment threaded apps - and is a simple and useful guide to the Singleton.
I've had a go at doing a thread safe version, which you may want to look at: http://www.codeproject.com/useritems/PDESingletonTemplateNoMFC.asp[^]
Cheers!
//////////////////////////////
// Paul Evans, UK.
//////////////////////////////
|
|
|
|
 |
|
 |
Just a theory:
With this method you have a memory leak because the delete for the Singleton is never called.
Instead of keeping a pointer to the object in the class you can rewrite the Instance function of the class like:
Singleton* Singleton::Instance()
{
static Singleton _cSingleton;
return &_cSingleton;
}
|
|
|
|
 |
|
 |
Definately the way I would have done it too, but his implementation does not create a leak because the very purpose is to create one and only one instance and the OS will clean up the heap used by the process when it dies.
"It could have been worse, it could have been ME!" -Rincewind
|
|
|
|
 |
|
 |
Ack...we shouldn't leave it up to the OS to clean up our messes.
Also, this method won't work if you have a Singleton that uses another Singleton. A create-on-demand method would be better. For instance:
Singletone* Singleton::s_singletonInstance = 0;
Singleton* Singleton::getInstance()
{
if ( 0 == s_singletonInstance )
{ s_singletonInstance = new Singleton(); }
return s_singletonInstance;
}
// adding an atexit() handler to clean up the alloc is left as
// an exercise to the reader.
Chris.
|
|
|
|
 |
|
 |
Chris Stoy wrote:
Also, this method won't work if you have a Singleton that uses another Singleton.
Why?, am I missing something here?...
Chris Stoy wrote:
// adding an atexit() handler to clean up the alloc is left as
// an exercise to the reader.
Hmmm, before replying to this I better get home and check what sort of subtle problems could be created when using a ( C ) atexit() callback that could possibly destroy singletons before C++ objects were through using them in their destructors...
class Foo
{
public:
~Foo()
{
Singleton * pSingleton = Singleton::getInstance();
pSingleton->someAmazingDestructionHelperMethod(this);
}
};
void OnExit(void)
{
Singleton * pSingleton = Singleton::getInstance();
delete pSingleton;
}
int main()
{
Foo foo;
atexit(OnExit);
return 0;
}
"After all it's just text at the end of the day. - Colin Davies
"For example, when a VB programmer comes to my house, they may say 'does your pool need cleaning, sir ?' " - Christian Graus
|
|
|
|
 |
|
 |
I've marked a race condition in the code below - the null check is only any good as a lock hint in a multiple threaded app.
Singleton* Singleton::getInstance()
{
if ( 0 == s_singletonInstance ) //Race condition here - possiblilty of 2+ singletons being created if code swapped out after this line
{ s_singletonInstance = new Singleton(); }
return s_singletonInstance;
}
You expect static variables to be cleaned up by the compiler. Of course static pointers are a whole different kettle of herring!
//////////////////////////////
// Paul Evans, UK.
//////////////////////////////
|
|
|
|
 |
|
 |
Actually it is better to leave the OS to clean up memory. If you explicitly clean up the OS must page the memory in from
disk just so you can delete it. If you just exit then all your dirty pages are marked "free" with no disk I/O. Freeing the memory might be desireable if you wish to avoid confusing messages from a leak analysis program but for production use let the OS clean up.
|
|
|
|
 |
|
 |
Let me get it straight...
You are saying that if I have a static variable, for example
static char* a;
and I assign it a value :
a = new char[1000];
will the OS will release all the allocated data (1000 bytes)?
I know that it will release the pointer variable, but i dont think it will release all the data pointed to..
|
|
|
|
 |
|
 |
Puponacid wrote:
I know that it will release the pointer variable, but i dont think it will release all the data pointed to..
I can assure you that it will, and that's very lucky for us unfortunate enough to run Exchange Server, because we only need to kill the server to get back all the memory that was leaked.
The memory you allocate using new() or malloc() is allocated within you application space, all that space will be reclaimed by Windows when you exit your app.
"After all it's just text at the end of the day. - Colin Davies
"For example, when a VB programmer comes to my house, they may say 'does your pool need cleaning, sir ?' " - Christian Graus
|
|
|
|
 |