Статьи

Учебные материалы по языку C++ — от основ до продвинутых тем

Заголовочные файлы, include и ODR

Страница 37 из 43 · 2026-10-25 · 1 мин чтения

Заголовочные файлы, include и ODR

Зачем нужны заголовки

Заголовочный файл (.h или .hpp) обычно содержит объявления, которые нужны другим частям программы. Файл .cpp содержит определения функций и реализацию.

// Math.h#pragma onceint Add(int a, int b);
// Math.cpp#include "Math.h"int Add(int a, int b) {    return a + b;}

Другой .cpp подключает Math.h и вызывает Add. Каждый .cpp компилируется отдельно, а затем объектные файлы связываются линкером.

Защита от повторного включения

#pragma once поддерживается распространёнными компиляторами. Альтернатива — include guards:

#ifndef MATH_H#define MATH_Hint Add(int a, int b);#endif

Ошибки линковки

Если функция объявлена, но нигде не определена, часто возникает ошибка undefined reference или unresolved external. Если обычное определение функции помещено в заголовок и включается в несколько .cpp, возможны множественные определения.

Для функции, определение которой находится в заголовке и включается в разные единицы трансляции, применяют inline при соблюдении правил ODR. inline не означает, что компилятор обязан встроить вызов.

Что помещать в заголовок

  • объявления типов и функций;
  • объявления классов и их членов;
  • шаблоны, которым требуется видимость определения;
  • короткие функции, определённые как inline.

Не включай лишние заголовки. По возможности используй предварительные объявления, если они безопасны и уменьшают зависимости.

Итог

Заголовок задаёт интерфейс, .cpp обычно содержит реализацию. Понимание единиц трансляции, include guards и ODR помогает быстро разбираться в ошибках линковки.