Introduction

When I first started dipping my toes into the ocean that is C++ I couldn’t understand header files at all. What is the point? Why do I need to declare a function there just to actually write the code for said function in another file? It sounds so utterly ridiculous, but I’m about to explain the reasoning, so buckle up buttercup.

Why do we need header files?

  1. Organization: They keep your code nice and neat by separating your declarations from your implementations.
  2. Reusability: You can reuse the same declarations in multiple .cpp files.
  3. No Duplication: You don’t need to copy & paste or reuse the same function declarations in different files.

In short: they keep you organized, and make your code easier to manage and scale.

Example

Let’s say we have three different files; maths_functions.h, maths_functions.cpp, and main.cpp, code for each below:

maths_functions.h
// Include guard to avoid double inclusion
#ifndef MATHS_FUNCTIONS_H
#define MATHS_FUNCTIONS_H
 
int add(int a, int b);  // Function declaration
int subtract(int a, int b);
 
#endif
maths_functions.cpp
 
#include "maths_functions.h"
 
int add(int a, int b) {
    return a + b;
}
 
int subtract(int a, int b) {
    return a - b;
}
main.cpp
 
#include <iostream>
#include "maths_functions.h"  // Include header
 
int main() {
    std::cout << "5 + 3 = " << add(5, 3) << std::endl;
    std::cout << "5 - 3 = " << subtract(5, 3) << std::endl;
    return 0;
}

So, maths_functions.h is telling other files what functions exist, a bit like a menu in a restaurant.
But maths_functions.cpp contains the actual code for the function, like the food in the kitchen!

Other .cpp files (like main.cpp) want to use the add function, but they don’t know about it until you tell them - that’s where the header file comes in!

Let’s break it down a bit. 🕺

Breaking it Down

Let’s stick with the kitchen analogies for now.

maths_functions.h (the “menu”)

int add(int a, int b);

So, this is a declaration. It’s basically just telling your compiler “hey, this function is called add, it takes two ints and then returns an int. Not telling you how it works though, lol”

Now, your main.cpp sees this beautiful tasty function on the menu and knows it exists, but it just doesn’t know how it works (or in this case, the ingredients that make the dish).

maths_functions.cpp (the “kitchen”)

int add(int a, int b) {
    return a + b;
}

Here is the definition of the function, or in other words, the ingredients that make up the dish. Now we know what’s involved in the dish itself!

main.cpp (the customer)

#include "maths_functions.h"  // Gets the declaration
 
int main() {
    int result = add(2, 3);
}

Now main.cpp knows add exists (because it saw it on the menu, maths_functions.h).

But you might be asking (as I did), how does main.cpp know what add does? All we’ve done is included the header but the function definition itself is still in maths_functions.cpp itself - a separate file. That’s where your linker comes in!

Linkers

Let’s say we have those 3 files from above, and compile it like this:

g++ main.cpp maths_functions.cpp -o my_program

Here’s what happens:

  1. main.cpp gets compiled and sees the function declaration in maths_functions.h
  2. maths_functions.cpp gets compiled, containing the actual function definition
  3. The linker connects the dots:
    • main.cpp is calling the add function.
    • maths_functions.cpp is defining add.
    • ok guess i better link em lol

Summary

main.cpp doesn’t need to include maths_functions.cpp itself, it just needs the header file to understand the add function exists.
Your compiler and linker will connect everything up when you build!

In Simple Terms:

The .h file tells the compiler what exists.
The .cpp file gives the actual code.
Other .cpp files include the .h to know what they’re allowed to use.

Any questions? I’d love to hear them and help out - let me know below. :-)