"Classes and Objects" section question

What’s the point of having both the song.cpp file and the song.hpp file?

It seems like the content in the .cpp file is just a more detailed version of what’s in the .hpp file. For example, song.cpp has:

void Song::add_title(std::string new_title) {

  title = new_title;

and song.hpp has

void add_title(std::string new_title);

Why do we need both?

I’m a bit rusty on the inner workings of the C++ compiler, but here goes…

The reason for the header files is because of how the C++ compiler creates the final program.

When you compile your C++ program, each .cpp file is individually compiled into its own compilation unit. When the compilation is complete, a separate program - the linker - joins the compilation units together into the complete program.

The compiler doesn’t know or care about which names are declared in which compilation unit. All it does is convert your C++ to machine code that the CPU understands. So, if you wanted to create a C++ class and use it across multiple source .cpp files you would need to declare the exact same object in every .cpp where you wanted to use it.

This, equally, means that if you wanted to change it you have to change it everywhere, and a single mistake in any one file that contains that declaration will cause errors for the linker.

Instead, by declaring the function/class/whatever in the header file (e.g. my_stuff.hpp) we can tell any .cpp file which needs to know about it what that function/class/object looks like - i.e. what type it returns, what its parameters are etc - using a single point of reference.

You then implement the function/class/whatever in a separate file, my_stuff.cpp, which includes the header - #include "my_stuff.hpp". The compiler literally copies-and-pastes that header into the source at compile time, merging the two into a single compilation unit to be passed to the linker. The end result is we have a single declaration of some_function(), a single implementation of some_function(), and no problems for the linker.

Say you had a source file superfunction.cpp which needs a function you’ve defined in utilities.cpp. By including the header utilities.hpp, you can tell superfunction.cpp about the basic structure of the objects declared in utilities.cpp. The actual functionality of those objects is incorporated into your final program by the linker, when it links the compilation units for superfunction.cpp and utilities.cpp.

That hopefully makes sense… it’s been a while since I’ve had to explain any of this.

If you’re confused, I’m sorry! If you search for information about how C++ compilation works, it should become clearer about why the headers are there and how they’re useful.