И так, для чего же нужны директивы препроцессора? Заголовочные файлы включаются в текст программы с помощью директивы препроцессора #include. Программа, которая обрабатывает эти директивы, называется препроцессором. Имя файла может быть указано двумя способами: #include или #include "my_file.h". Если имя файла заключено в угловые скобки (<>), считается, что нам нужен некий стандартный заголовочный файл, и компилятор ищет этот файл в предопределенных местах. Двойные кавычки означают, что заголовочный файл - пользовательский, и его поиск начинается с того каталога, где находится исходный текст программы. При этом обычно имя файла который заключен в (<>) это стандартные библиотеки самого языка или же внешние, путь к котором нужно прописывать в настройках проекта, тот же пример #include . В *.h файлах определяются типы, классы, прототипы функций, объявляются переменные (что они где-то есть), кода в *.h файлах нет за исключением inline функций (т.к. при компиляции каждый cpp файл видит только подключённые к нему *.h, поэтому тела inline функций берутся из них). Затем происходит сборка. Если сборка обнаружит совпадения имён или использование только объявленных (но не существующих) переменных - возникают ошибки сборки. Для стандартных *.h файлов существуют скомпилированные объектные файлы, поэтому им cpp не требуется, т.к. всё нужное они черпают оттуда. Добавка: назначение *.h файла простое - разделение кода программы на несколько файлов. Структура разделения такова: создаем test.h файл в котором будет определятся класс и его методы, затем создается test.сpp и там уже инициализируем методы класса. Вообще разницы нету, в *.h файле я могу определить любую функцию , а затем подключив в main.cpp через #include <*.h> смог бы ее вызвать, также как и если б она была в самом файле main.cpp, но семантически это не верно и так делать не надо.