Forward Declarations
As we have mentioned before, the C/C++ compiler is very primitive. In order to use something, a function, procedure, variable, or constant, the compiler must have already seen its declaration.
This means that the language needed a way of forward declaring things. These are like promises to the compiler that you will build thing you are declaring somewhere else in the code. The compiler will then trust you, and the linker will fail if the thing you declared does not exist when everything is finally put together.
Header Files
Header files are full of forward declarations of functions, procedures, and constants. If we think about the “splashkit.h” header, it tells the compiler “trust me… there is an open_window
funtion with three parameters - a string and two doubles”. This means you can call open_window
and the linker is then told to look in the SplashKit library where it finds the code we have written to create this.
Multiple cpp files
Using header files, you can now start to code your program using multiple files. Each C/C++ file can contain a part of the programs code with the shared things declared in a header file. This can be a great way to help further organise the code in your program.
Make sure to only use forward declarations in your header files. You will potentially include these in multiple files. If you declare a function or a procedure in the code, then it will be created multiple times. This will then become an issue - so watch out for errors relating to re-defining things that already exist.
To help protect against this, the C/C++ pre-processor includes the ability to skip code in a file using either a #ifdef
or a #ifndef
guard. These guards only include code if something is declared (#ifdef
) or not declared (#ifndef
).
In general, you wrap all code in each header file in its own unique guard like this:
This says, if GAME_LOGIC_H
is not defined, then include the code that follows up to the matching #endif
. The second line then declares GAME_LOGIC_H
, ensuring that any subsequent include of this header file does will skip this code as the GAME_LOGIC_H
is now defined.
Example
We can split our global variables example across multiple files like this:
In program.cpp:
The logic.h header can forward declare the elements that main needs.
Which can then be coded into logic.cpp. The compiler will not care what the filename is called, but this will help us link the two together as we go forward.
To compile this, we now need to compile both cpp files. If these are the only files in the current folder, then you can use the “*.cpp” wildcard to compile all cpp files. Alternatively, you can list each of the filenames in the call.
You do not include the header files in the compiler call. The preprocessor will read those for you and embed their code where the #include
is encountered.