Re-usable singleton class that can construct pointers to objects with non-trivial constructors
As the topic says, I wanted to make a re-usable singleton class that
could create pointers to objects with non-trivial constructors. I came
up with this:
#ifndef SINGLETON_HPP
#define SINGLETON_HPP
template<typename T>
struct DefaultCreatorFunctor
{
T * operator()() const { return new T; }
};
template<typename T>
struct ValueCreatorFunctor
{
ValueCreatorFunctor(const T& val) : val_(val) {}
T * operator()() const { return new T(val_); }
private:
T val_;
};
/* Users can add more functors for more elaborate types. */
template <typename T1, typename T2>
class Singleton
{
public:
static T1 * get_instance(const T2& creator)
{
if (!obj)
{
obj = creator();
}
return obj;
}
private:
Singleton() {}
static T1 *obj;
};
template <typename T1, typename T2>
T1 * Singleton<T1, T2>::obj = 0;
#endif /* #ifndef SINGLETON_HPP */
As you can see I've provided to default functor, one for default-
constructing and one for objects with a constructor that takes a
single value.
I've made the following test program:
#include <iostream>
#include <string>
#include "singleton.hpp"
using namespace std;
int
main()
{
int *n = Singleton<int, ValueCreatorFunctor<int>
::get_instance(ValueCreatorFunctor<int>(4711));
cout << *n << endl;
delete n;
string *s = Singleton<string, DefaultCreatorFunctor<string>
::get_instance(DefaultCreatorFunctor<string>());
cout << *s << endl;
delete s;
return 0;
}
it seems to work but somehow I don't feel very satisfied. The syntax
for obtaining an instance is not elegant and if you want to a more
elaborate class to be handled as a singleton, you will have to write
your own functor (basically a ValueCreatorFunctor with additional
parameters). It was however a good exercise in templates and functors
for me and for that I'm glad.
Also I was thinking about ways in which I could make the singleton
delete its pointer when the program exits, so the user doesn't have to
worry about that (and risk double deletes).
As always, I would like comments from you. :-)
- Eric