2010-02-04 1 views
6

Я знаю это, чтобы предотвратить множественное включение файла заголовка. Но предположим, что я обязательно включу этот файл только в один .cpp-файл только один раз. Есть ли еще сценарии, в которых я бы требовал этого охранника?Назначение #ifndef FILENAME .... # endif в файле заголовка

+0

Спасибо всем. Крис получает его за то, что он разрабатывает :) – deeJ

+0

В следующий раз мне нужно сломать свою репутацию, я просто запомню, чтобы публиковать, откладывая мою домашнюю работу. :) –

ответ

7

Вы можете гарантировать, что ваш код включает в себя только один раз, но вы можете гарантировать, что кто- «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 он снова и сломал некоторый код, и требуется несколько часов, чтобы понять, почему существуют противоречивые определения вещей.

12

Нет, это единственная цель включения охранников, но использование их должно быть беспроблемным: для этого требуется мало времени и, возможно, экономит много.

1

Это его единственный смысл. Это по-прежнему хорошая идея, даже если вы думаете, что у вас это покрыто; это не замедляет ваш код или что-то еще, и ему никогда не мешает иметь дополнительную охрану.

1

Целью защиты является то, что файл не был re включен в один файл .cpp более одного раза. Он не защищает от включения файла в несколько файлов .cpp.

Если вы уверены, что заголовочный файл не включен в другой файл заголовка, тогда защита не требуется. но это все еще хорошая форма.

еще лучше форма использовать

#pragma once 

если ваш компилятор поддерживает его.

+0

Включенный охранник лучше ИМХО, потому что он более портативный. Я избегаю зависимости от специфичных для компилятора функций, таких как чума. –

+2

@Chris: важности переносимости для открытого кода. Но обычно не для закрытого источника. #pragma один раз более надежный и быстрый, чем защита, потому что компилятор действительно может _сканировать_сканирование файла. Это то, что на самом деле имеет значение в закрытом магазине. –

+0

GCC фактически оптимизирует включенную идиоматию охранника, чтобы сделать по существу то же самое. Но я согласен с тем, что для базы данных с закрытым исходным кодом, использующей Visual Studio, '#pragma once' вполне подходит. –

1

Обеспечение того, чтобы ваш код был включен только один раз, является единственной целью так называемой «защиты заголовка».

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

0

Дополнительный сценарий, который я могу придумать (и мы его сделали), - создать 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; 
    } 
} 
0

Использование охранника заголовка, как это ускоряет процесс компиляции, представьте себе, три исходных файлов с помощью заголовка (минус охраннику заголовка), что в свою очередь будет означать компилятор должен включать заголовок (разбор и lexing синтаксис) несколько раз.

С защитой заголовка компилятор скажет: «Ха! Я видел это раньше, и нет, я не буду разбирать/lex синтаксис, «тем самым ускоряя процесс компиляции.

Надеюсь, это поможет, С уважением, Tom.

Смежные вопросы