Я знаю это, чтобы предотвратить множественное включение файла заголовка. Но предположим, что я обязательно включу этот файл только в один .cpp-файл только один раз. Есть ли еще сценарии, в которых я бы требовал этого охранника?Назначение #ifndef FILENAME .... # endif в файле заголовка
ответ
Вы можете гарантировать, что ваш код включает в себя только один раз, но вы можете гарантировать, что кто- «S код будет включать его один раз?
Кроме того, представьте себе:
// a.h
typedef struct { int x; int y; } type1;
// b.h
#include "a.h"
typedef struct { type1 old; int z; } type2;
// main.c
#include "a.h"
#include "b.h"
О, нет! Наши main.c
включали только один раз, но b.h
включает в себя a.h
, поэтому мы получили a.h
дважды, несмотря на все наши усилия.
Теперь представьте себе скрытые за три или более слоев #include
с и это незначительное внутреннее использование только заголовок, который получает включены в два раза, и это проблема, потому что один из заголовков #undef
эд макрос, который он определен, но второй заголовок #define
d он снова и сломал некоторый код, и требуется несколько часов, чтобы понять, почему существуют противоречивые определения вещей.
Нет, это единственная цель включения охранников, но использование их должно быть беспроблемным: для этого требуется мало времени и, возможно, экономит много.
Это его единственный смысл. Это по-прежнему хорошая идея, даже если вы думаете, что у вас это покрыто; это не замедляет ваш код или что-то еще, и ему никогда не мешает иметь дополнительную охрану.
Целью защиты является то, что файл не был re включен в один файл .cpp более одного раза. Он не защищает от включения файла в несколько файлов .cpp.
Если вы уверены, что заголовочный файл не включен в другой файл заголовка, тогда защита не требуется. но это все еще хорошая форма.
еще лучше форма использовать
#pragma once
если ваш компилятор поддерживает его.
Включенный охранник лучше ИМХО, потому что он более портативный. Я избегаю зависимости от специфичных для компилятора функций, таких как чума. –
@Chris: важности переносимости для открытого кода. Но обычно не для закрытого источника. #pragma один раз более надежный и быстрый, чем защита, потому что компилятор действительно может _сканировать_сканирование файла. Это то, что на самом деле имеет значение в закрытом магазине. –
GCC фактически оптимизирует включенную идиоматию охранника, чтобы сделать по существу то же самое. Но я согласен с тем, что для базы данных с закрытым исходным кодом, использующей Visual Studio, '#pragma once' вполне подходит. –
Обеспечение того, чтобы ваш код был включен только один раз, является единственной целью так называемой «защиты заголовка».
Это может быть полезно, как если бы между вашими заголовочными файлами была круговая зависимость, вы не попадаете в бесконечный цикл включения файлов.
Дополнительный сценарий, который я могу придумать (и мы его сделали), - создать C++ mocks.
Вы явно указали в файле build GUARD значение, а затем можете добавить свою собственную реализацию макета через -include my_mock.h в качестве дополнительного параметра компилятора (мы использовали g ++).
my_mock.h
#define THAT_FILE_GUARD
class ThatClass
{
void connect()
{
std::cout << "mock connect" << std::endl;
}
}
Использование охранника заголовка, как это ускоряет процесс компиляции, представьте себе, три исходных файлов с помощью заголовка (минус охраннику заголовка), что в свою очередь будет означать компилятор должен включать заголовок (разбор и lexing синтаксис) несколько раз.
С защитой заголовка компилятор скажет: «Ха! Я видел это раньше, и нет, я не буду разбирать/lex синтаксис, «тем самым ускоряя процесс компиляции.
Надеюсь, это поможет, С уважением, Tom.
- 1. #ifdef/#ifndef и #endif
- 2. Зацикливание над конструкциями ifndef/endif в Makefile
- 3. Назначение выражения CMake ENDIF
- 4. Что эффективно использовать #pragma once или #ifndef #endif?
- 5. Как включить блоки «# ifndef/# endif» в сборках makefile?
- 6. Лучшая практика в файлах заголовков C с #ifndef #define #endif
- 7. Почему код между ifndef/endif все еще запущен?
- 8. Вызов функции в файле заголовка
- 9. Файл заголовка включен дважды, несмотря на #ifndef
- 10. Использование необъявленной идентификатора в файле заголовка (Clang)
- 11. ошибка swig: extraneous #endif
- 12. Структуры из одного файла заголовка в другом файле заголовка
- 13. Использование define в файле заголовка c
- 14. Использование Typedef из одного файла заголовка во втором файле заголовка
- 15. Inluding функции в файле заголовка
- 16. Полный макрос в файле заголовка
- 17. множественного определения в файле заголовка
- 18. Использование int в файле заголовка?
- 19. несовместимо # если/# endif пара в * .h файле
- 20. Функция, объявленная дважды в файле заголовка C
- 21. Быстрый вопрос относительно условной компиляции (ifndef)
- 22. C++ объявление класса в другом файле заголовка
- 23. Андроид HTTP-заголовка filename ignored
- 24. Назначение от несовместимых типов указателей, из структуры в файле заголовка
- 25. Определение функций в файле заголовка с помощью примитивов в другом файле заголовка
- 26. аргументы Передача по ссылке в файле заголовка
- 27. Объявление векторов в файле заголовка C++
- 28. Поведение неинициализированного глобальной переменной в файле заголовка
- 29. Использование структуры в файле заголовка «неизвестный тип»
- 30. Почему переменная в файле заголовка дает ошибку?
Спасибо всем. Крис получает его за то, что он разрабатывает :) – deeJ
В следующий раз мне нужно сломать свою репутацию, я просто запомню, чтобы публиковать, откладывая мою домашнюю работу. :) –