Какова функция include guard в.cpp (не в.h)?

Хорошо, может быть, на этот вопрос уже есть ответ, но я не знаю, какое ключевое слово для поиска (большинство моих результатов поиска о включении охранника в .h только, но не в .cpp)

Иногда я видел в cpp каждый #include В линии есть дополнительный защитный кожух (иногда даже включенный .h уже есть собственная защита включения), например: SomeClass.cpp

#ifndef__A__
#include A.h
#endif
#ifndef__B__
#include B.h
#endif
#ifndef__C__
#include C.h
#endif

вместо

SomeClass.cpp

#include A.h
#include B.h
#include C.h

Какова функция этого включить охранник?

3 ответа

Джон Лакос (John Lakos) рекомендовал практику использования включенных средств защиты в файлах.cpp в своей книге Large-Scale C++ Software Design. Я не знаю, рекомендовал ли кто-нибудь до него практику.

Скажи у тебя

Ах:

#ifndef __A__
#define __A__

#include "B.h"
#include "C.h"

// ...
// ...
// ...

#endif

Bh:

#ifndef __B__
#define __B__

// ...
// ...
// ...

#endif

Ch:

#ifndef __C__
#define __C__

// ...
// ...
// ...

#endif

SomeClass.cpp:

#ifndef __A__
#include "A.h"
#endif

#ifndef __B__
#include "B.h"
#endif

#ifndef __C__
#include "C.h"
#endif

Когда SomeClass.cpp компилируется, содержимое Ah включается. В качестве побочного продукта, включающего в себя содержание Ah, также включается содержание Bh и Ch. Кроме того, макросы препроцессора __A__, __B__ а также __C__ определены. Когда линия

#ifndef __B__

обрабатывается, так как __B__ уже определено, следующая строка пропущена.

Если бы SomeClass.cpp имел только:

#include "A.h"
#include "B.h"
#include "C.h"

файл Bh должен быть открыт и обработан. Содержимое файла больше не будет включено из-за включенных защит, но файл должен быть открыт и закрыт.

Используя первую стратегию, вы избегаете затрат на открытие и закрытие Bh и Ch. Для крупномасштабного проекта C++, утверждает Джон Лакос, стоимость слишком велика. Следовательно, рекомендации по использованию включают охрану даже в.cpp файлах.

Это означает, что даже не проверяйте содержимое файла заголовка, если файл уже включен (symbol_specific_to_header определено).

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

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

Вот так выглядит и включается заголовочный файл.

Новый стиль:

/* A.h */
#pragma once
...

или же

/* A.h */
#ifndef A_H
#define A_H
...
#endif

использование:

#include "A.h"

Или используются предварительно скомпилированные заголовки.

Старый стиль

Древний стиль, как вы упомянули:

/* A.h */
#define A_H
...

использование:

#ifndef A_H
#include "A.h"
#endif

Это защита от включения одного и того же заголовка дважды.

Ах может выглядеть примерно так

#define __A__
#include B.h

Без охраны Bh будет включен дважды, что может привести к ошибкам. Таким образом, строки #ifndef в cpp просто защищают себя от заголовков, включая другие заголовки.

Другие вопросы по тегам