Re: StateFull vs Stateless Singleton
On 4 juuli, 23:58, sebastian <sebastianga...@gmail.com> wrote:
On Jul 4, 9:02 am, Pallav singh <singh.pal...@gmail.com> wrote:
Hi
what the consideration parameter to choose stateless and statefull
Singleton ?
Thanks
Pallav Singh
Neither - a simple template class eliminates the issue altogether:
<code>
#include <stdexcept>
template < typename Type >
class singleton
{
public:
singleton( void )
{
Type* ptr = static_cast< Type* >( this =
);
if( self )
{
/*
Or what have you...
*/
throw std::runtime_error
(
"Error: a=
ttempt to instantiate multiple instances of a singleton"
);
}
self = ptr;
}
static inline Type& instance( void )
{
return *self;
}
static inline bool exists( void )
{
return self != 0;
}
virtual ~singleton( void )
{
self = 0;
}
private:
singleton( singleton const& );
singleton& operator = ( singleton const& );
static Type* self;
};
template < typename Type >
Type* singleton< Type >::self = 0;
// Example:
#include <iostream>
class foo : public singleton< foo >
{
public:
void bar( void ) const
{
std::cout << "foo::bar( )" << std::endl;
}
};
int main( void )
{
try
{
foo a;
foo::instance( ).bar( );
foo c; // Whoops!
foo::instance( ).bar( );
}
catch( std::exception const& error )
{
std::cerr << error.what( ) << std::endl;
}
}
</code>
The beauty of the design is that it allows the user to decide how to
allocate and initialize the derived class; it's sole purpose is to
make sure that multiple instances aren't created. Best of all, it's
completely generic!
Cheers.
Looks as beautiful like any other reinvented square wheel. The
requirements seem to be that such code must work:
int main( void )
{
{
foo a;
foo::instance( ).bar( );
}
foo c; // Second singleton and *NO* Whoops
foo::instance( ).bar( );
}
Not sure why someone needs to have global state? Typical example of
singletons is a logger. Huh? So ... OK. What if i need to have
separate logs from different modules? I will then need new class for
each log to have separate singleton logger for each module? Nonsense.
What if i need to have separate logs from different threads? Then that
Logger::instance() should give me "different" singletons based on
thread ID? Huh? Why it can't just be debugging::log() and where it
logs is its internal business, no global state no nothing?
As for your code ... same thing with 10-12 lines instead of 70-80:
#include <iostream>
namespace foo
{
void bar()
{
std::cout << "foo::bar()" << std::endl;
}
}
int main()
{
foo::bar();
}
Things that contain nothing are not worth allocating or initializing.