ImGui manager singleton For my game engine I am implementing ImGui for debugging purposes. In order to manage ImGui I have made a singleton to make sure only one ImGui context gets created. I am not entirely sure if this is a good implementation of a Singleton so I am looking for some feedback, also is using a Singleton here the right way or could I better use a full static class?

ImGUIManager.h

#ifndef CHEETAH_CORE_IMGUIMANAGER_H_
#define CHEETAH_CORE_IMGUIMANAGER_H_

#include "Core.h"
#include "../ImGUI/imgui.h"

#include &lt;memory&gt;

namespace cheetah
{
    class CH_API ImGUIManager
    {
    public:
        static void init();
        static void shutDown();
        static void begin();
        static void end();

        static inline ImFont* getTextFont() { return ImGUIManager::getInstance()-&gt;m_text; };
        static inline ImFont* getIconSmallFont() { return ImGUIManager::getInstance()-&gt;m_iconSmall; };
        static inline ImFont* getIconLargeFont() { return ImGUIManager::getInstance()-&gt;m_iconLarge; };

        virtual ~ImGUIManager() = default;

    protected:  
        ImGUIManager() = default;
        virtual void init_impl() = 0;
        virtual void shutDown_impl() = 0;
        virtual void begin_impl() = 0;
        virtual void end_impl() = 0;

    protected:
        ImFont* m_text = nullptr;
        ImFont* m_iconSmall = nullptr;
        ImFont* m_iconLarge = nullptr;

    private:
        static ImGUIManager* getInstance();
        static void create();

    private:
        static std::unique_ptr&lt;ImGUIManager&gt; m_instance;
    };
}

#endif // !CHEETAH_ENGINE_IMGUI_IMGUIMANAGER_H_


ImGUIManager.cpp

#include "ImGUiManager.h"
#include "Renderer/RenderAPI.h"
#include "Platform/OpenGL/OpenGLImGUIManager.h"

namespace cheetah
{
    std::unique_ptr&lt;ImGUIManager&gt; ImGUIManager::m_instance = nullptr;

    void ImGUIManager::init()
    {
#ifdef DEBUG
        static bool initialized = false;
        ASSERT(!initialized, "ImGUI is already initialized");
#endif // DEBUG
        ImGUIManager::getInstance()-&gt;init_impl();
#ifdef DEBUG
        initialized = true;
#endif
    };

    void ImGUIManager::shutDown()
    {
        ImGUIManager::getInstance()-&gt;shutDown_impl();
    };

    void ImGUIManager::begin()
    {
        ImGUIManager::getInstance()-&gt;begin_impl();
    };

    void ImGUIManager::end()
    {
        ImGUIManager::getInstance()-&gt;end_impl();
    };

    ImGUIManager* ImGUIManager::getInstance()
    {
        if (!m_instance)
            ImGUIManager::create();

        return m_instance.get();
    }

    void ImGUIManager::create()
    {
        switch (RenderAPI::getAPI())
        {
        case RenderAPI::API::OpenGL:
            m_instance = std::make_unique&lt;opengl::OpenGLImGUIManager&gt;();
            break;
        default:
            m_instance = nullptr;
        }
    }
}
Its not thread safe!

Looks like you can still create instances manually (though you would have to derive a class that can use the protected constructor) or copy the one created by getInstance().

Why not use the classic Singleton pattern?

class ImGUIManager
{
     public:
         static ImGUIManager&amp; getInstance()
         {
             static ImGUIManager instance;   // static member
                                             // Correctly constructed on first use.
                                             // Will be deleted on exit.
             return instance;
         }
         // PUT YOUR INTERFACE HERE

     private:
         ImGUIManager(){} // Make sure the constructor is private.
         // Delete the copy and move constructors.
         ImGUIManager(ImGUIManager const&amp;)            = delete;
         ImGUIManager&amp; operator=(ImGUIManager const&amp;) = delete;
         ImGUIManager(ImGUIManager&amp;&amp;)                 = delete;
         ImGUIManager&amp; operator=(ImGUIManager&amp;&amp;)      = delete;
};


Some References:

C++ Singleton design pattern