Да, знаю.
Существует два основных способа:
Использование директив препроцессора (#ifndef, #define, #endif):
c
При первом включении файла FILENAME_H, макрос FILENAME_H еще не определен, поэтому блок кода между #ifndef FILENAME_H и #endif будет обработан препроцессором. Внутри этого блока определяется макрос FILENAME_H. При последующих включениях этого же файла в пределах одной единицы трансляции, FILENAME_H уже будет определен, и блок кода будет проигнорирован.
Использование директивы #pragma once:
c
Эта директива является нестандартной (хотя поддерживается большинством современных компиляторов) и сообщает компилятору, что данный файл должен быть включен только один раз в пределах одной единицы трансляции. Компилятор самостоятельно отслеживает это и предотвращает повторное включение.
Сравнение:
| Характеристика | #ifndef/#define | #pragma once |
|---|---|---|
| Стандартизация | Является частью стандарта C/C++ | Не является частью стандарта C/C++ |
| Поддержка компиляторами | Широкая (все стандартные компиляторы) | Широкая (большинство современных) |
| Простота использования | Требует уникального имени макроса | Проще, не требует уникальных макросов |
| Стойкость к переносам | Более устойчив к копированию файла под другим именем | Может быть менее устойчив при копировании |
Оба подхода эффективно предотвращают повторное включение, что необходимо для корректной компиляции и предотвращения ошибок, связанных с множественным определением сущностей (классов, функций, переменных).