where does singleton come to play?

Started by
18 comments, last by nilkn 18 years, 10 months ago
class singleton { static singleton * m_singleton;singleton(){m_singleton = new singleton;} ... }; singleton d; so I will use singleton::m_singleton->member instead of d->member. so singleton just use class name instead of instance name to access member. singleton just play this role. so am I right?
Advertisement
More-less: yes.

But you have to be carefull about initializing your singleton. It could go like this:
/* in your "Terrain.h" */class CTerrain{    // ...some code...public:    static CTerrain *singleton;};/* in your "Terrain.cpp" */// ...some code...CTerrain* CTerrain::singleton = NULL; // I bet you don't want to initialize here./* in some other .cpp file */bool initTerrain(/*some params*/){    // ...some code...    CTerrain::singleton = new CTerrain(/*construction params?*/);    // ...some more code(eg. graphic setings)...}void releaseTerrain(void){    if (CTerrain::singleton) {        CTerrain::singleton->Release();        delete CTerrain::singleton;        CTerrain::singleton = NULL;    }}


Now, the important thing is that you got to have full control of all data in your program. So implicit construction and initialization is (usually) a bad thing (the code: "singleton(){m_singleton = new singleton;}" is an infinite loop). So if you've got to know where construction and destruction takes place, and in which order, 'cause your singletons usually will have to use each other even in initialization code.

Cheers.
/def
Singletons generally have a minimum of these two properties.
  1. There can only be one instance.
  2. The instance is not created until it is referenced.


There are a few ways of implementing a singleton. Here is a very simple one:
    class Singleton    {    public:         static Singleton & Instance()        {            if ( !m_pInstance )            {                m_pInstance = new Singleton;            }            return *m_pInstance;        }     private:          Singleton();                    // Prevent construction by others        Singleton( const Singleton & ); // Prevent copying        static Singleton * m_pSingleton;    };     Singleton::m_pInstance = 0; 


John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
I really see no benefit to singletons except in entirely object-oriented languages like Java, where in, for instance, a server environment, it's likely that multiple clients may be using the same virtual machine and need access to the same object, which must only be instantiated once. (And in this case it can be very useful; we use it at work all the time.)

The purpose of a singleton is to ensure that an object is instantiated once and only once. This is usually because the object represents something that logically only exists once, like the video subsystem or (I still gag thinking of things like "CGameEngine") God forbid the engine.

However, in that instance I think that you're actually misusing the purpose of a class. C++ classes are very good for some things: encapsulation, inheritance, polymorphism, etc. If you're going to use a singleton, then you're not going to be using inheritance, you're not really encapsulating much because in essence you just have a glorified struct that is only being created once, and you can't very well use polymorphism if you don't inherit. So why even bother creating a whole class for something that will be instantiated once?

My preferences; if want to hide information about "singular" objects like the video subsystem or the game engine, declare them static in their own module and keep state information there locally. Then just use standard function calls to do the interaction as you would with any member functions your singleton would have called.

Then you also avoid having to keep pointers around in every single place you want to acccess that information.
i'm not really contributing to the topic but i DO have a related question. Been using singleton's on several occasions and they were handy. But it just crossed my mind that although instantiation is only ONCE, how do you prevent accidental deletion?

a singleton instantiates itself on first reference: easy to do by protecting the constructors and allowing a GetInstance-kind of function. But by that, you will get back a pointer.

What is to stop someone from accidentally deleting the pointer? I personally use a specific shutdown function to force termination of a singleton, but i neva actually tried deleting it directly (mainly coz i created the functon for a purpose :P ). Can accidental 'delete' be prevented?
- To learn, we share... Give some to take some -
Quote:Original post by Omaha
If you're going to use a singleton, then you're not going to be using inheritance...


One of the purposes of a singleton over a static class is so you can use inheritance. Say you have a Renderer class that uses SDL and you want to make a subclass of it that uses Direct3D or OpenGL.
Sure, you can still just a global object, but thats got its own problems.

EDIT: Also, I believe you can override the delete operator and make it private. THat'd solve the problem of accidental deletions of the singleton object.
A very clever Singleton interface I wrote a while back (I got the concept from some article, can't remember the name though):

		template< typename Type >		class ISingleton		{		public:			ISingleton()			{				assert( !s_singleton );				int offset = sizeof( ISingleton< Type > ) - sizeof( Type );				s_singleton = reinterpret_cast< Type* >( reinterpret_cast< int >( this ) + offset );			}			~ISingleton()			{				assert( s_singleton );				s_singleton = 0;			}			static Type& Get()			{				assert( s_singleton );				return *s_singleton;			}			static Type* GetPointer()			{				assert( s_singleton );				return s_singleton;			}		private:			static Type* s_singleton;		};		template< typename Type > Type* ISingleton< Type >::s_singleton = NULL;


Example Usage:
class Renderer : public ISingleton<Renderer>{     void Render();};void main(){     new Renderer;     Renderer::Get().Render();}
I too use that class (from I would guess the same article).

You can also use

#define renderer Renderer.Get()

So that you need only type "renderer.render();".
[ search: google ][ programming: msdn | boost | opengl ][ languages: nihongo ]
Quote:Original post by CraZeE
What is to stop someone from accidentally deleting the pointer? I personally use a specific shutdown function to force termination of a singleton, but i neva actually tried deleting it directly (mainly coz i created the functon for a purpose :P ). Can accidental 'delete' be prevented?



You don't have to return a pointer:

template<class T>class singleton{public:   static T& getInstance()   {      if(!instance)      {          instance = new T;      }      return *instance;   }private:   static T* instance;};template<class T>T* singleton<T>::instance = 0;


Then you just derive any class you want to be a singelton from singleton with the template parameter as itself.


Quote:template<class T>
class singleton
{
public:
static T& getInstance()
{
if(!instance)
{
instance = new T;
}
return *instance;
}
private:
static T* instance;
};


template<class T>
T* singleton<T>::instance = 0;


what is "T* singleton<T>::instance = 0;"?
it is a function? because have return type T*.
it is a memeber of data? because ::instance is static T* instance;


This topic is closed to new replies.

Advertisement