Что происходит до компиляции
Когда препроцессор встречает `#include`, он подставляет текст заголовочного файла на место директивы. Если в заголовке есть собственные `#include`, обработка продолжается и для них. В результате компилятор получает не набор файлов, соединённых во время работы программы, а подготовленный текст одной единицы трансляции — части программы, которую компилируют как целое.
Это объясняет, зачем заголовки обычно содержат объявления функций и типов: исходный файл должен узнать, например, какие аргументы принимает функция, прежде чем сможет проверить вызов. Реализацию функции часто помещают в отдельный `.cpp`-файл и компилируют самостоятельно; затем компоновщик связывает полученные объектные файлы в программу.
Почему заголовок подключают не один раз
Один и тот же заголовок может попасть в исходник напрямую и через другие заголовки. Повторно объявить некоторые сущности допустимо, но повторное определение типа или функции в одной единице трансляции обычно приводит к ошибке. Чтобы этого избежать, используют защиту включения — условные директивы, которые разрешают обработать содержимое заголовка только при первом подключении. Часто для той же цели пишут `#pragma once`.
Текстовая подстановка также влияет на организацию кода. Если изменить заголовок, все исходные файлы, которые от него зависят, могут потребовать повторной компиляции. А определения шаблонов часто оставляют прямо в заголовках: компилятору нужен их текст там, где шаблон применяют с конкретными типами.
Подстановка — не копирование во время запуска
После предварительной обработки отдельного шага «подключить этот заголовок» в работающей программе уже нет. Заголовок влияет на то, что компилятор увидит и проверит, но сам по себе не становится отдельной частью исполняемого файла. Поэтому небольшая директива может незаметно подтянуть целую цепочку объявлений — и увеличить объём работы при пересборке проекта.





