views:

119

answers:

4

Ok, I should simply tell that I want to make a base Singleton class that I can inherit from, and the way I want to achieve that is by a template.

In order to avoid memory leaks, I do not use directly a pointer to the instance, but a private class that will handle deleting the pointer.

Here is my actual code (not working) :

template <typename T> class Singleton
{
private:
    class PointerInstance
    {
    private:
        T* instance;
    public:
        PointerInstance() : instance(0) {}
        ~PointerInstance() { delete instance; } // no memory leak !
        T* Get()
        {
            if ( !instance ) {
                instance = new T();
            }
            return instance;
        }
    };
    static PointerInstance PInstance;
public:
    static T* pGetInstance(void)
    {
        return PInstance.pGet();
    };
protected:
    Singleton(void){};
    ~Singleton(void){};
};

And here is what a typical derived class declaration should look like :

class Child : public Singleton<Child>
{
    friend class Singleton<Child>;
    Child();
    // etc...
};

Basically what is lacking is the instance of PInstance for each T class I make as a Singleton.

My question is : is there a way to do this once and for all with a few generic lines of code in the Singleton.h containing the code above, or do I have no other choice but to add a few specific lines of code for each derived class ?

(Bonus : is there a better way to do a Singleton class in C++ ?)

+5  A: 
template <typename T> 
typename Singleton<T>::PointerInstance Singleton<T>::PInstance;

In the header outside of the classes. Note that whatever you write in PInstance's default constructor, the code will never be executed if you never call pGetInstance or never refer to PInstance in another way from non-template code. But that should be fine.

Johannes Schaub - litb
Thanks, that works fine !
teupoui
+2  A: 

Here is a simpler way of writing a CRTP Singleton without a memory leak:

template <class T>
class Singleton
{
  friend class T;
private:
  Singleton() {};
  ~Singleton() {};
  Singleton(const Singleton&); // not implemented
  const Singleton& operator=(const Singleton&); // not implemented

public:
  static T* pGetInstance()
  {
    static T theInstance;
    return &theInstance;
  }
};

Usage is the same as in the question.

Bart van Ingen Schenau
Why return a pointer. Return a reference from pGetInstance(). It is never going to be NULL and you don't want the user to accidentally get the idea that they can delete it.
Martin York
This is close to what we call "Meyers Singleton". It only should return reference to instance, not pointer.
Valentin Heinitz
@Martin, Valentin: I wanted to keep the interface as close to the one in the question as possible. Otherwise, I agree that returning a reference is better.
Bart van Ingen Schenau
Ok this looks really better than what I was going on. I juste have the folloing errors with "friend class T;" and then errors with private constructors everywhere... Any idea how I can do without making protected constructors ? error: using template type parameter ‘T’ after ‘class’ error: friend declaration does not name a class or function
teupoui
@teupoui In C++0x, you write `friend T;`, in C++03 there is no way to befriend a template parameter. What's wrong about protected constructors anyway?
Johannes Schaub - litb
A: 

Maybe you want to take a look at Loki which already has a generic SingletonHolder<> class?

Philipp
Thank you, but I think Loki's code is a little bit too complex for my case (their Singleton file is 946 lines of code for example). I will have a look at it but I don't think I will see much interesting here, compared to the answers I have already got.
teupoui
Well, USING the singleton class definitely requires less lines to write than writing your own class. (See the Loki section in http://www.oreillynet.com/network/2003/05/06/cplusplusian.html, for a short example, there's actually ~3 lines required for using it. And you only pay for what you need - the many lines in the file are caused by several Policies which you choose from (or use the defaults). This gives you lots of flexibility for later requirements such as multithreading or more complex lifetime management. I'd prefer existing code over own, but it's up to you.
Philipp
A: 

First in general I would suggest you avoid using singletons where possible. They are horribly overused.

If you have to use them, I really do not get this new popular way (must have appeared in a journal somewhere because I see everyone using it now) of deriving from Singleton. Doing this causes as many problems as it solves.

If you have to have one though, the best way to initialise it is to use boost::once. You need to do something like this in your source where Foo is your class.

these 3 are all statically declared in Foo and private

Foo* Foo::instance = NULL;
boost::once_flag Foo::flag = BOOST_ONCE_INIT;
void Foo::init()
{
   Foo::instance = new Foo;
};

This is also static and is the public method to get the instance

Foo & Foo::getInstance()
{
   boost::call_once(init, Foo::flag);
   return *Foo::instance;
}

The constructor of Foo must not throw.

Note that this technique can be used more extensively for thread-safe once-loading lazy-evaluation situations, not just singletons. The new version of boost::once takes first the flag (which is now a struct: beware) and secondarily takes a boost::function so you can boost::bind in information for creation.

For deleting your singleton, you can create a boost::shared_ptr at compilation unit level and bind your pointer to it, and use a custom deleter that is a static member of your class so that delete can remain private. Your deleter will be able to call delete though, and your init function will have access to the deleter function (which is also private) to initialise the shared_ptr with it.

CashCow
Thank you, but I want my program to be able to run on a lot of different platforms that may not all have Boost available. I prefer to use an independent solution.
teupoui