Jump to content
  • Advertisement
Sign in to follow this  
derek7

where does singleton come to play?

This topic is 4813 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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?

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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;


Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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();
}

Share this post


Link to post
Share on other sites
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();".

Share this post


Link to post
Share on other sites
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.


Share this post


Link to post
Share on other sites
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;


Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!