How do I implement the singleton I describe without circular inclusion?

Started by
4 comments, last by larspensjo 10 years, 6 months ago

I have a class called 'Window' which essentially contains everything need to run my program. Inside window, I have 'Simulation', 'Renderer' and 'InputController' classes. In some instances, these classes need access to a global pointer to a 'Window'. For example: I have a DrawDebug() function in 'Renderer' which needs to get information about the status of the Simulation so it can be drawn as text on screen. I'm not sure exactly how to go about doing this and some help would be much appreciated. Thanks :)

J.W.
Advertisement
First, let me say that your design is appalling. A window is a rectangular piece of screen, and it should know nothing about simulation, renderer or input controller. The fact that you sometimes need a pointer to a window means that everything inside window is effectively global, so you may as well make Simulation, Renderer and InputController global and stop pretending that you have some design.

Now, as to how to prevent circular inclusion, the header file for your Window class should probably include all the header files for the other classes, and the header files for the other classes should use a forward declaration, like this:
  class Window;
This will allow you to use pointers to Window without having to include the header file for Window.

Why not just have this

 
// A function to get access to the singleton at anytime so there is no need for any parameters for the Window class
class Window
{
public:
    static Window* getInstance()
    {
        static Window instance;
        return &instance;
 
    }
};
 
// You can also do it with dynamic memory instead of a static instance, which is preferred.

Because few people would consider a window to be a good candidate for singleton usage.

Yes, that looks so wrong. The window would be created at a totally random time or even never if noone asks for the pointer.

And later someone wants two windows...

Programming is much about keeping the number of dependencies as low as possible. With many dependencies, the source code is difficult to modify. When you find yourself in the situation that you have cyclic dependencies of header files, it is a sign that you may be doing something wrong. Of course, there are valid use cases, but I try to avoid them.

In worst case, using header guards, recursion can be avoided at the cost of strange compilation errors.

The use of forward declaration may solve this. It is actually a good general principle. Use it wherever possible, so as to avoid including header files.

[size=2]Current project: Ephenation.
[size=2]Sharing OpenGL experiences: http://ephenationopengl.blogspot.com/

This topic is closed to new replies.

Advertisement