Header Files
We want both cowchat.cpp and cowmath.cpp to have a declaration of printMoos but we don't want to have to literally type it in both files.
The solution is to create a header file to contain the line that they should have in common and then use #include in both of the .cpp files to copy the header file's contents into both files before compilation.
We give our header files an extension .hpp to distingish them from source files (.cpp). Source files need to be compiled, header files need to be #included by something else, not compiled in their own right.
We will put the declaration of our printMoos function in a new header file printmoos.hpp.
printmoos.hpp:
// Header file for printMoos
void printMoos(int numMoos);
cowchat.cpp:
#include "printmoos.hpp"
#include <iostream> // for std::cin, std::cout
#include <string> // for std::string
int main() {
std::cout << "Chat with a cow!";
std::string userIn;
do {
std::cout << std::endl // New line
<< "> "; // The prompt
std::getline(std::cin, userIn);
int nMoos = 1 + userIn.size() % 2;
// ^-- Either 1 or 2 moos;
printMoos(nMoos);
} while (std::cin.good() && userIn != "");
std::cout << "\n\nBye!\n";
return 0;
}
cowmath.cpp:
#include "printmoos.hpp"
#include <iostream> // for std::cin, std::cout
int main() {
std::cout << "Cow math!\n";
std::cout << "Enter the first number: ";
int x = 0;
std::cin >> x;
std::cout << "Enter the second number: ";
int y = 0;
std::cin >> y;
if (std::cin.good()) {
std::cout << "The cow goes: ";
printMoos(x + y);
std::cout << std::endl;
} else {
std::cout << "\n\nSomething went wrong!\n";
}
return 0;
}
The highlighted lines are replaced by the preprocessor with the contents of printmoos.hpp before compilation. Thus both files have a forward declaration of the printMoos function without our having to duplicate the code for that declaration!
Even better, we don't need to make any changes to printmoos.cpp, so we can use exactly the same set of compilation commands as before:
clang++ -c printmoos.cpp
clang++ -c cowchat.cpp
clang++ -c cowmath.cpp
clang++ -o cowchat cowchat.o printmoos.o
clang++ -o cowmath cowmath.o printmoos.o
Notice that printmoos.hpp does not appear anywhere in the compilation commands! We don't need to compile the file separately because the preprocessor adds its contents where we've used #include in cowchat.cpp and cowmath.cpp.
Why is it called a “header file”?
We usually think of a function as having two parts: a header and a body. The header is the part before the first curly brace that gives the function's name, parameters, and return type. The body is the part between the curly braces, and defines the actual instructions for the function. Header files typically only contain headers, because their primary purpose is to make forward declaration easier.
Could a header file contain other things?
Sure! Sometimes header files declare variables, classes, and other things.
What about
iostreamin#include <iostream>? Is that a header file?
It totally is! It declares a bunch of stuff related to input and output streams. It declares classes like
std::istreamandstd::ostreamand also variables likestd::coutandstd::endl.
Funny story: when the C++ standards were being created, nobody could agree on the file extension for header files. The compromise was to make header files for the standard library have no file extension at all! That's why it's
iostreaminstead ofiostream.hpporiostream.horiostream.hxxor whatever.
In CS 70 we will use
.cppfor source files and.hppfor header files.
(When logged in, completion status appears here.)