Re: Singleton --- Just Look and give Suggestion's
On Mar 5, 6:15 pm, srdgame <srdg...@gmail.com> wrote:
=E4=BA=8E Thu, 05 Mar 2009 08:16:45 -0800=EF=BC=8CPallav singh=E5=86=99=
=E5=88=B0=EF=BC=9A
[...]
My perferred Singleton way, If I want to make class A to be
singleton, I will declear it as:
class A : public Singleton< A >
{
}
With a semicolon after the }, of course:-).
This is more or less the standard idiom, of course.
namespace srdgame
{
template <class T>
class Singleton
{
public:
static T* get_instance()
{
return &(get_singleton());
}
static T& get_singleton()
{
static T instance;
return instance;
}
~Singleton(){};
protected:
Singleton(const Singleton& sig);
Singleton& operator = (const Singleton& sig);
Singleton(){};}
;
This has the disadvantage that the singleton will be destructed
some time when static objects are destructed. This usually
isn't what is wanted.
My own singleton uses a policy to control this:
<code>
// DestructionPolicy:
// ==================
//
//! Determines whether the destructor will be called on exit or
//! not. (Unless there is a very strong reason to call it, it is
//! recommended that it not be called, so as to avoid order of
//! destruction issues.)
//
---------------------------------------------------------------------------
enum DestructionPolicy
{
neverDestruct,
destructOnExit
} ;
// Singleton:
// ==========
//
//! Makes a singleton for UserClass. If UserClass should always
//! be a singleton, it can derived from this template class,
//! declaring this template class as friend and its constructor as
//! private.
//!
//! This implementation is thread safe if and only if the first
//! call to instance takes place before threading starts. This
//! template ensures that the constructor is called at least once
//! during static initialization; on normal implementations, this
//! means that the singleton will be thread safe if threading is
//! not started before main.
//
---------------------------------------------------------------------------
template< typename UserClass, DestructionPolicy dtorPolicy =
neverDestruct >
class Singleton
{
public:
static UserClass& instance() ;
private:
static UserClass* ourInstance ;
template< DestructionPolicy discrimPolicy >
class Discrim {} ;
static UserClass* createInstance( Discrim< neverDestruct > ) ;
static UserClass* createInstance( Discrim< destructOnExit > ) ;
} ;
template< typename UserClass, DestructionPolicy dtorPolicy >
UserClass* Singleton< UserClass, dtorPolicy >::
ourInstance
= &Singleton< UserClass, dtorPolicy >::instance() ;
template< typename UserClass, DestructionPolicy dtorPolicy >
UserClass&
Singleton< UserClass, dtorPolicy >::instance()
{
if ( ourInstance == NULL ) {
ourInstance = createInstance( Discrim< dtorPolicy >() ) ;
}
return *ourInstance ;
}
template< typename UserClass, DestructionPolicy dtorPolicy >
UserClass*
Singleton< UserClass, dtorPolicy >::createInstance(
Discrim< neverDestruct > )
{
return new UserClass ;
}
template< typename UserClass, DestructionPolicy dtorPolicy >
UserClass*
Singleton< UserClass, dtorPolicy >::createInstance(
Discrim< destructOnExit > )
{
static UserClass theOneAndOnly ;
return &theOneAndOnly ;
}
</code>
Like yours, it's meant to be derived from. This seemed so
obvious to me that I forgot to document it. (One should
probably also assign a UserClass* to a Singleton< UserClass >*
somewhere in the code, so that it won't compile *unless*
UserClass derives from it.)
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=C3=A9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=C3=A9mard, 78210 St.-Cyr-l'=C3=89cole, France, +33 (0)1 30 23 00 =
34