The real problem with singletons is the way in which they are implemented, IMO. Typically, raw memory allocation is used and a lack of error propagation when multiple objects are instantiated (the whole point of using a singleton in the first place!). Luckily, designing a generic singleton class that covers all of the important bases is fairly trivial:
Code:
template < typename Class >
class singleton
{
public:
singleton( void )
{
if( instance_ )
throw *( Class* )this;
instance_ = ( Class* )this;
}
virtual ~singleton( void )
{
instance_ = 0;
}
static Class& global( void )
{
return *instance_;
}
protected:
singleton( singleton const& )
{ }
static Class*
instance_;
};
template < typename Class >
Class*
singleton< Class >::instance_ = 0;
Upon instantiation, the singleton "attaches" itself to the global instance, however it was allocated (ie: stack/heap); so long as no other object of that type is "alive" at that moment, no error occurs - otherwise, an exception is thrown. This affords one the flexibility to create scoped singletons on the stack, repeatedly from the heap, or even using a combination of the two! And note that when an exception IS thrown it's simply a reference to the offending instance, which can be caught as either a reference to Class OR a reference to a singleton<Class> (the latter syntax can be useful for clarity).
Example usage would simply be:
Code:
class RadioStatistics : singleton<RadioStatistics>
{
private:
map<string, int> m_songs;
map<string, int> m_singers;
RadioStatistics();
public:
string getMostPlayedSong();
string getMostPlayedSinger();
};
Notice that I got rid of all of the other static members; trust me, they aren't necessary and only serve to muddle up your design. You can either access everything via RadioStatistics::global( ), directly from the object you instantiated, or from some "wrapper" object that essentially forwards all of the global() calls to itself.