Заголовки и единицы трансляции
Функцию triple определяют в triple.cpp, а вызывают из main.cpp, report.cpp и других файлов программы. Компилятор (compiler) примет каждый вызов, только если выше него стоит объявление (declaration) int triple(int x);. Копировать это объявление в каждый файл вручную ненадёжно. Если тип параметра (parameter) поменяют в одной копии и забудут про остальные, файлы начнут объявлять разные функции.
Заголовочный файл
Объявление пишут один раз, в заголовочном файле (header) — файле с объявлениями, который подключают туда, где они нужны. Файл main.cpp подключает его директивой #include:
#include <iostream>
#include "triple.h"
int main() {
std::cout << triple(14) << '\n'; // 42
}Директива #include вставляет на своё место текст заголовка triple.h, а в нём одна строка — объявление:
int triple(int x);Имя своего заголовка пишут в кавычках, а заголовка стандартной библиотеки — в угловых скобках. Заголовок обычно называют так же, как .cpp-файл с определениями (definitions). Определение остаётся в triple.cpp, и этот файл тоже подключает triple.h:
#include "triple.h"
int triple(int x) {
return x * 3;
}Теперь объявление и определение стоят в одном файле. Если они разойдутся по типу результата, компилятор сообщит об ошибке ещё при компиляции triple.cpp.
Единица трансляции
Компилятор переводит не отдельный файл, а единицу трансляции (translation unit): .cpp-файл вместе со всем текстом, который вставили в него директивы #include. Каждую единицу он компилирует отдельно, в свой объектный файл (object file). Заголовок сам по себе не компилируется: его текст входит в каждую единицу, которая его подключила. Поэтому в команде сборки (build) перечисляют только .cpp-файлы: clang++ main.cpp triple.cpp.
Так программу делят на части: заголовок сообщает, какие функции есть, а .cpp-файл — как они работают. Подключить заголовок могут сколько угодно файлов программы. Объявление теперь записано в одном месте, и компилятор сверяет с ним каждый вызов.
Частая ошибка
Свой заголовок подключили в угловых скобках:
#include <iostream>
#include <triple.h> // ✗
int main() {
std::cout << triple(14) << '\n';
}error: 'triple.h' file not found with <angled> include; use "quotes" insteadЭто ошибка компиляции. В угловых скобках компилятор ищет заголовок среди каталогов библиотек, а папку, где лежит main.cpp, не просматривает. С кавычками поиск начинается с папки самого файла.