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?
- Organization: They keep your code nice and neat by separating your declarations from your implementations.
- Reusability: You can reuse the same declarations in multiple
.cpp
files. - 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:
// 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
#include "maths_functions.h"
int add(int a, int b) {
return a + b;
}
int subtract(int a, int b) {
return a - b;
}
#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 int
s 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:
main.cpp
gets compiled and sees the function declaration inmaths_functions.h
maths_functions.cpp
gets compiled, containing the actual function definition- The linker connects the dots:
main.cpp
is calling theadd
function.maths_functions.cpp
is definingadd
.- 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. :-)