Once per cpp file. Once you understand how *.h and *.cpp files are actually used, you'll understand why. I will now explain enough for you to understand it and know for yourself when to include header files.
Here is what happens when you build an executable or library made of more than one cpp file.
Each cpp file is examined by the preprocessor. If it finds any
#include somefile
, the complete contents of the file somefile is copied into the cpp file at that point.
Then, the compiler takes each cpp file (which now has the contents of various header files written into it, just as if you had cut and paste it there yourself with your text editor) and compiles it into a binary object file.
Each cpp file is dealt with individually, so each cpp file must include any headers it needs itself.
When all the cpp files have been compiled into binary object files, the linker gets to work. All those object files are linked together. If you're making a library, that's pretty much it. If you're making an executable, the linker links them together with some system specific objects and presents the output executable (the system specific bits take care of setting things up when you run the executable, and there will be something in there that calls your main function).
If an object file contains an identical function definiton to that in another object file, the linker will not know which one to use when you call the function - this is what goes wrong when you put the same function definition in more than one cpp file.
How does the compiler know which cpp files to compile? Because the compiler is a command-line tool, and when you call it, you call it with the names of the files to compile:
g++ file1.cpp file2.cpp file3.cpp |
If you're using an IDE, it may hide this from you. It's still doing it.
How does the linker know which object files to link? Because the linker is a command-line tool, and when you call it, you tell it which object files to link, much like the compiler. Again, if you're using an IDE, it may hide this from you. It's still doing it.