2007-04-11

Tidying Up and Organising Header Files

(Written 02/04/2007)

Not much time to work on this today, so I’ve decided to spend the time I have got in tidying up the layout of the code. I’ve split the slideshow up so that all of the classes are now in separate files, rather than all being in the main.cpp file. After an awful lot of fiddling and researching, I’ve found that:

  • Header files (*.h) should include all headers required by the related *.cpp file, regardless of whether they are included elsewhere in the project;
  • Header files should include guards (#ifndef, #endif) around them to stop them being included more than once;
  • *.cpp files with the same name as the *.h file are included automatically;
  • *.cpp files should include their own header files;
  • It makes things much easier if you split the class definition from the actual functionality, keeping the definition in the *.h and the functionality in the *.cpp.

Here’s an example *.h layout:

#ifndef _MYHEADER_H_ 
#define _MYHEADER_H_ class

MyClass {
private:
    u8 myInt;

public:
    MyClass();
    void setMyInt(u8 myInt);
    u8 getMyInt();
};

#endif

We wrap the whole thing in a preprocessor #ifndef block, which will stop it being included more than once. This is apparently the standard way of doing things; the alternative is to use “#pragma once”, or something like that, but it’s probably something invented by Microsoft.

Next, this is an example *.cpp layout for the above header:

#include "myheader.h"

using namespace std;

MyClass::MyClass() {
   myInt = 0;
}

void MyClass::setMyInt(u8 myInt) {
    MyClass::myInt = myInt;
}

u8 MyClass::getMyInt() {
    return myInt;
};

You can see that the methods are all extracted from the class definition and included in the separate file. Each method that belongs to the class is prefixed with the class’s namespace, which in this case is “MyClass::“.

Doing things in this way means that, in order to include a whole library of functions in the project, we just need to include the single header file for that whole library. In the case of Defender, I just include “slideshow.h” in order to get the entire slideshow (consisting of 4 classes and 4 header files) included. It also means that the class “forward definition” is compiled into the main project, which avoids all sorts of problems.

Even more handily, it means that it’s incredibly easy to see all of the various members and methods of a class without the code getting in the way. The downside to this is that the code is no longer nested inside the class itself, which seems to me (having started out with Java as my first “proper” OO language, and having worked with VB.NET and C#.NET every day for the past 18 months) to be rather ugly.