Re: singleton template
Nick Keighley wrote:
mlimber wrote:
Nick Keighley wrote:
Hi,
I found this in code I was maintaining
template <class SingletonClass>
SingletonClass* Singleton<SingletonClass>::instance ()
{
static SingletonClass _instance;
return &_instance;
}
there are indications that the constructor is getting called more than
once
in some circumstances (tracing in one of the instantiations of the
template).
Are there potential problems with the use of static data?
There are sometimes, but there's nothing inherently wrong with this
code (you might consider using references instead, however). See
chapter 6 of _Modern C++ Design_ for more than you ever wanted to know
about singletons in C++
.
thanks, I keep on meaning to getting around to MCD, but I am not
comfortable with templates.
You might want to try to look through at least chapter 6 because he
discusses some of the pitfalls with singletons in C++ (including in
multithreading, longevity, etc.) and ways to handle them.
For instance something like this:-
class PerformanceDataItemIniFile : public PanelIniFile,
public Singleton< PerformanceDataItemIniFile >
...
worries me it inherits from something that uses itself as a parameter.
That's the Curiously Recurring Template Pattern (see, e.g.,
http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern) and
can be quite useful. However, with singletons, I would expect to see
something more like this for your template class:
template<class T>
class Singleton
{
public:
static T& Instance();
private:
// Disabled functions
Singleton();
Singleton( const Singleton& );
Singleton& operator=( const Singleton& );
Singleton* operator&();
~Singleton();
};
template<class T>
T& Singleton<T>::Instance()
{
static T myObject;
return myObject;
}
Which is not inherited from but used as a wrapper like this:
class A
{
private:
// Private constructor/destructor disallows creation
// except by friends.
friend class Singleton<A>;
A();
~A();
// Disabled functions for singleton usage
A( const A& );
A& operator=( const A& );
A* operator&();
public:
void DoSomething();
// ...
};
Singleton<A> theA;
void Foo()
{
theA::Instance().DoSomething();
}
Cheers! --M