Search code examples
c++templatesconstructorsingletonprivate

templated singleton class - how to handle private constructor


I realize how many times this have been talked about but I have not found an appropriate solution for my problem. I have just implemented a Meyer's singleton class into my project but I would like to make a template out of it so that I can use it as e.g.

class Game : public Singleton<Game> { /* stuff */ }

And I have my class defined like this

template <typename T>
class Singleton
{
public:
    static T& Instance();

private:
    Singleton();
    //declare them to prevent copies
    Singleton(Singleton const&);
    void operator=(Singleton const&);

};// END OF CLASS DEFINITION


// METHODS' DEFINITIONS

template<typename T>
T& Singleton<T>::Instance()
{
    static T _instance;
    return _instance;
}

Allowing ctor to be public will destroy whole vision of Singletons.

EDIT Ok, so I have updated my Game class to befriend Singleton<Game>

class Game : public Singleton<Game>
{
friend class Singleton<Game>;
//...
}

But now I have something like:

undefined reference to 'Singleton< Game >::Singleton()'

in function Game::Game() which is empty


Solution

  • Allowing ctor to be public will destroy whole vision of Singletons.

    No, not really. Game should have a private constructor. Constructor of Singleton is irrelevant. An instance of Singleton<Game> will not help anyone to get another instance of Game, which is what you're interested in.

    Anyway, you can declare the constructor protected. Alternatively, you can keep the constructor private and befriend the template parameter. Except this does not work in C++03. Should work in C++11 though. But there's a little trick:

    template <typename T>
    struct wrapper
    {
        typedef T type;
    };
    
    template <typename T>
    class Singleton
    {
        friend class wrapper<T>::type;
    

    Update: Game should befriend Singleton<Game>, or at least Singleton<Game>::Instance, to allow its constructor to be called.