Should a Source File Include Its Own Header File?
Should a source file include its own header file?
Hmm. Good question. What do you think?
In fact, either answer can be considered correct! That's because, in this particular example, they are both reasonable.
Technically, printmoos.cpp does not need #include "printmoos.hpp" because it does not require a forward declaration of the function printMoos. The function definition given in printmoos.cpp also serves as a declaration.
On the other hand, it is a good idea in general for source files to include their own header files.
An Example
To see why a source file might need to include its own header, consider this file:
moobaa.cpp:
in fenced code block
void printMooBaa(int n) {
printMoo(n);
}
void printMoo(int n) {
if (n > 0) {
std::cout << "Moo! " << endl;
printBaa(n);
}
}
void printBaa(int n) {
if (n > 0) {
std::cout << "Baa! " << endl;
printMoo(n - 1);
}
}
Imagine you are the compiler. You are going through this code line by line… what happens?
First, printMooBaa calls printMoo, but printMoo hasn't been declared yet! Then, printMoo calls printBaa, but printBaa also hasn't been declared yet.
The solution: forward declaration! We can add a header file,
moobaa.hpp:
#ifndef MOOBAA_INCLUDED
#define MOOBAA_INCLUDED
void printMooBaa(int n);
void printMoo(int n);
void printBaa(int n);
#endif
and #include our new header file in our code file,
moobaa.cpp:
#include "moobaa.hpp"
void printMooBaa(int n) {
...
Now all our functions have been declared before they're used: our code will compile!
Upshot
In general, it is best practice for a .cpp file to #include its own .hpp file so functions get forward declared.
But, like, how often am I really going to have some complicated recursion like that?
True. But even when there is an order that would declare everything, do you always want to spend time figuring it out?
For that matter, is that necessarily how you want to organize your code?
So, it's not always strictly necessary for a source file to include its own header file…
But it is usually a good idea. At the very least it frees you from worrying about the order of your functions!
Okay, that's another chunk done. Head up to the parent page to see your progress and take a break if you need it!
(When logged in, completion status appears here.)