måndag 15 augusti 2011

When to forward declare?

Ok. I have just realized that the structure of my source code files isnt very good at all. Ok, I didnt just realize it, I have known it for a while. But I havent bothered to fix it until now. First thing I'm doing is making sure that each class is contained in its own header file. Next up I'm going to separate my project into logical parts, which will serve as namespaces.
Im going to fix the directory structure aswell,to reflect the namespaces in the project.

My concern is; When should one forward declare a type?
Take the vtx_render.h (soon to be renamed to vtx_rendermanager.h!) for instance, which contains the following:

#ifndef VTX_RENDER_H
#define VTX_RENDER_H

// ...
#include <vortex/vtx_window.h>


class RenderManager : VortexBase
{
public:
        RenderManager(Root&);
        void init(RenderCreationParams &params, WindowCreationParams &windowParams);
        void destroy(void);
        RenderAPI *getRenderObject(void);
private:
        void createWindow(WindowCreationParams &params);
        NativeWindow *window;
        bool manageWindow;
        RenderAPI *render;
};


#endif

Notice that WindowCreationParams used as input parameter to the init and createWindow methods. The class WindowCreationParams is defined in vtx_window.h

Since our limited use of WindowCreationParams, we do not need the entire definition of the class and so the include of vtx_window isn't really necessary. I can just forward declare WindowCreationParams:

#ifndef VTX_RENDER_H
#define VTX_RENDER_H

// ...
class WindowCreationParams;


class RenderManager : VortexBase
{
public:
        RenderManager(Root&);
        void init(RenderCreationParams &params, WindowCreationParams &windowParams);
        void destroy(void);
        RenderAPI *getRenderObject(void);
private:
        void createWindow(WindowCreationParams &params);
        NativeWindow *window;
        bool manageWindow;
        RenderAPI *render;
};


#endif

The pros for this include:
  • Improved compilation time.
  • Reduces risk of cyclic dependency.
  • ... possibly something else I'm not thinking about.
The cons:
  •  If the class being forward declared is removed or renamed, the header using the forward declaration will  not be affected, instead the error will not show until in the source files including this header.
  • Semi-related to the above point; having to keep all forward declarations up to date concerning class name/containing namespace.
  •  Template classes can not be forward declared (?) This is not really an issue per se, just a restriction (that is easy to work around!).
  •  ... possibly something else I'm not thinking about ;)
I know no one is reading this, but I would still appreciate your input!

(Edit: I forgot to say, I intend to use forward declarations whenever possible, unless I find a good reason not to!)

Inga kommentarer:

Skicka en kommentar