Как защитить header-файл от повторного включения в C++

«Как защитить header-файл от повторного включения в C++» — вопрос из категории C++ Core, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В C++ для защиты заголовочного файла от множественного включения и связанных с этим ошибок переопределения используются два основных метода.

1. Include Guards (Стражи включения) Стандартный, переносимый способ, который работает везде.

// File: my_class.h
#ifndef MY_CLASS_H // Если макрос не определен...
#define MY_CLASS_H // ... определяем его.

class MyClass {
    // ... объявление класса ...
};

#endif // MY_CLASS_H

Правила для имени макроса: Оно должно быть уникальным в рамках проекта. Обычно используют имя файла в верхнем регистре с подчеркиваниями (например, PROJECT_PATH_MY_CLASS_H).

2. Директива #pragma once Нестандартная, но широко поддерживаемая всеми основными компиляторами (GCC, Clang, MSVC) директива.

// File: my_class.h
#pragma once

class MyClass {
    // ... объявление класса ...
};
Сравнение: Критерий #pragma once Include Guards
Стандарт Не входит, расширение компилятора Стандартный C/C++
Скорость компиляции Может быть быстрее (компилятор отслеживает файлы) Медленнее (препроцессор проверяет макросы)
Надежность Может не сработать при симлинках или копиях файла Абсолютно надежна, если имя макроса уникально
Удобство Кратко, не требует придумывания имени Требует уникального имени и трех строк кода

Моя практика: В современных кроссплатформенных проектах на C++ я использую #pragma once из-за удобства и скорости. Однако для библиотек, требующих максимальной переносимости, или в корпоративных стандартах, запрещающих нестандартные расширения, следует использовать Include Guards.