Home > Back-end >  Template interface singleton
Template interface singleton

Time:03-23

I was hoping to use an interface to make a generic template class I can add to any other class to easily create singletons. (By easily create singletons I mean avoid having to re-write the 6 lines for GetInstance)

template <class T>
class Singleton
{
public:
   static T* GetInstance();
};

template<class T>
inline T* Singleton<T>::GetInstance()
{
 static T* myInst;

 if (!myInst)
 {
    myInst = new T();
 }

 return(myInst);
}

The only issue is that with this to work I have to have the constructor for the class be public, which I would like to avoid as it sort of ruins the Singleton design pattern.

Is there a solution I may not be aware of to get an instance for the generic type without having a public constructor? I do realise this might be a stupid question but I would really like this class to work.

Thanks

CodePudding user response:

First of all, your singleton should look differently as yours isn't thread safe. Then there are at least 2 solutions. First, is to make a particular instantiation a friend, so it would look something like this:

template <class T>
class Singleton
{
public:
    static T* GetInstance();
};

template<class T>
T* Singleton<T>::GetInstance()
{
    static T myInst;
    return &myInst;
}

class Test
{
public:
    void print()
    {
        std::cout << "Hello!\n";
    }
private:
    Test() = default;
    friend class Singleton<Test>;
};

That would require the modification of the user class which isn't ideal. So we can employ another solution like this:

template <class T>
class Singleton: private T
{
public:
    static T* GetInstance();
private:
    using T::T;
};

template<class T>
T* Singleton<T>::GetInstance()
{
    static Singleton<T> myInst;
    return &myInst;
}

class Test
{
public:
    void print()
    {
        std::cout << "Hello!\n";
    }
protected:
    Test() = default;
};

The only modification to the user class is making its ctor to be protected instead of private which is not a problem, in my opinion. The limitation is that the user class should not be final.

  •  Tags:  
  • c
  • Related