Какова функция 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 просто защищают себя от заголовков, включая другие заголовки.