«

Nov 16

C++: A singleton base class

C++: A singleton base class

Hi everyone, here is an example I used in a project of mine in order to generate singleton in a easier way.

The main goal was to remove much of the boiler plate from the class itself and try to wrap it inside a base class.

By googling around  I found many interesting approaches, and also on game programming gem 1 there is a nice template based  example, but the main problem with those approaches was that all of them were based on the assumption that your class need to be instantiated otherwise you return a null pointer, I don’t like that idea, I don’t want to clutter the code all over the place checking for a null pointer.

Of course since I am working on some sort of game engine I can just create all the singleton at boot up and be done with it, but I wish to reuse singleton in other project and I wanted a general way to implement that. The singleton I usually write just does a check if the pointer is null when you request it, if it is, it makes an instance and returns it. Pretty simple, so I tried to merge both workflows and here is the result.

#pragma once

template < typename T>
class Singleton
{
public:
	static inline T* get_instance()
	{
		if (!m_instance)
		{
			m_instance = new T;
		}
		return m_instance;
	}

	static inline T& get_reference()
	{
		if (!m_instance)
		{
			m_instance = new T;
		}
		return *m_instance;
	}

	static inline bool exists()
	{
		return m_instance != nullptr;
	}

	static inline void clean_up()
	{
		if (m_instance)
		{
			delete m_instance;
		}
                m_instance = nullptr;

	}
	virtual ~Singleton(void)
	{
		m_instance = nullptr;
	}

protected:
	static T* m_instance;
};

template < typename T>
T* Singleton< T>::m_instance = nullptr;

How it works is pretty simple, we created a template class, passing the class we wish to be able to make a singleton, all this is just to be able to auto generate boilerplate code
making the singleton being a singleton.
So we declare a couple of methods returning the correct pointer type and reference ,also handling the creation of the class and the creation of the static pointer for our variable.
Finally we also initialize the static pointer to nullptr.

Fairly straight forward but how does it work? fairly simple here is an example:


#include <core/singleton.h>

class Constants : public Singleton<Constants>
{

 friend Singleton<Constants>;

 public:

     void set_path(const char * exec_path);
     void set_window(GLFWwindow * window);

 private:
     Constants(); //private constructor
     Constants( Constants const&)=delete; //private copy constructor
 Constants& operator=(Constants const &)=delete; //private assignemnt operator

Here is a part of a class I use to hold constants for my engine, the only thing you need to do is to inherit from Singleton passing in the current class type of the child class and you are done (make all constructors private as-well).
I know it twisted my brain a little to think what the compiler does, but in the end template resolution is not so different from a macro, if you think a little you will see everything unroll niceley.
There is one gotcha you need to be aware of, you might have noticed that we need a friend declaration to the base class. This is needed because in a proper singleton you should not be able to instantiate the singleton by its constructor, so should be private, but if it is private the base class cannot access it (trough the template resolution), this mean we need the friend declaration. I am willing to live with that, doesn’t look ugly and I think overall is an elegant solution to the problem.
Let me know what you think about it!

 

PS: Special thanks to Alan Stanzione for helping me figure out I was using friend declaration the other way around 😀

Leave a Reply