All the preprocessor does is substitute the contents of the header file in place of the #include directive, before the compiler sees the code. A C++ compiler will be just as happy with code from the preprocessor as it will be if you copy the contents of the header file verbatim into your source file. So, for the compiler, header files are unnecessary.
Note that the preprocessor and the compiler are separate phases of the process of turning a C++ source file into an object file. The preprocessor does text substitution that changes source code. The compiler gets into the act later.
The value of header files is that they provide a convenient way to reuse code (typically declarations) in multiple source files. Programmers find it easier to type #include "someheader.h" than they do to repeatedly copy and past a thousand lines of text into multiple source files. Programmers also find it easier to edit someheader.h (and have their changes be seen by the compiler when processing ALL of their source files) than to edit content that has been duplicated across multiple source files. Making exactly the same change in multiple source files is tedious, boring, and error-prone. For humans. That is, in essence, the maintainability argument.
In C++ (and C) it is generally preferable to use the standard header files (<iostream>, etc) rather than copy and past the code from those headers into your source files. The contents of standard headers are implementation dependent (i.e. can vary between compilers), so a "copy and paste" approach can yield code that works with one compiler but not another.
Incidentally, you might want to contemplate the import keyword in Java. It is not equivalent to the #include preprocessor directive in C++, by any means, but there are aspects in common.