-2

I am trying to make a framework using SDL 2.0 and O-OP.

Here I have a CGraphicsManager class:

namespace tde {
    class CGraphicsManager : public Singleton<CGraphicsManager>
    {
    private:
        static SDL_Window* mWindow;
        static SDL_Renderer* mRenderer;

    public:
        ~CGraphicsManager();

        static Uint32 Init(const char* title, Vector2i& size, Uint32 flags);
        static SDL_Window* getWindow(){ return mWindow; }
        static SDL_Renderer* getRenderer() { return mRenderer; }
    };
}

And when I try to do so:

SDL_RenderClear(Graphics.getRenderer());

The compiler says:

error C2248: Singleton::Singleton can't reach private member in Singleton<'tde::CGraphicsManager'>

I tried to make mWindow and mRenderer static members but this way don't work. Help me to store window and renderer somehow in this sistem to make them visible and avalible in tde namespace!

Martin G
  • 17,357
  • 9
  • 82
  • 98
Erli Moen
  • 11
  • 3

1 Answers1

0

Ok, to make it all work required a bit of reading... This Boost singleton page suggested to me that the inheriting class needs to have a public default constructor, despite it being a Singleton.

The following code example compiles. Note the changes I made to Singleton and CGraphicsManager:

template<typename T>
class Singleton
{
    protected:
    Singleton() { };
    Singleton(const T&);
    Singleton& operator=(const T&);

    public:

    static T& getInstance() {
        static T instance;
        return instance;
    }

    ~Singleton() { };
};

namespace tde
{
    class CGraphicsManager : public Singleton<CGraphicsManager>
    {
    private:
        SDL_Window* mWindow;
        SDL_Renderer* mRenderer;

    public:
        CGraphicsManager() { } 
        ~CGraphicsManager() { };

        unsigned Init(const char* title, unsigned& size, unsigned flags);
        SDL_Window* getWindow(){ return mWindow; }
        SDL_Renderer* getRenderer() { return mRenderer; }
    };
}

I gave Singleton::Singleton() and Singleton::~Singleton() trivial implementations. I also made all these methods protected instead of private, so the inheriting class can invoke them.

I made all the methods and members in CGraphicsManager non-static. And, I gave CGraphicsManager::CGraphicsManager() and CGraphicsManager::~CGraphicsManager() trivial implementations also.

This compiles now, and Graphics.getRenderer() appears to do the right thing.

After all that, I question the value of inheriting from the Singleton<> template class. The usual way I implement a Singleton is to just embed these methods directly, or use a friend function that has a static local, rather than outsourcing it to a parent class. Most of the issues seem to revolve around method visibility between parent and child in the inheritance hierarchy.

Joe Z
  • 17,413
  • 3
  • 28
  • 39