Проблемы с C++ Header Guard

Я делаю небольшой C++ фреймворк, который содержит много.h и.cpp.

Я создал общее включение, которое включает все мои файлы.h, такие как:

framework.h

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

каждый заголовок.h защищен включением защиты, таким как

#ifndef A_HEADER
#define A_HEADER
...
#endif

Проблема в том, что я хотел бы иметь возможность включать "framework.h" во все sub.h, например, но это вызывает много ошибок компилятора:

#ifndef A_HEADER
#define A_HEADER

#include "framework.h"
...
#endif

Если вместо этого я использую реальный заголовочный файл для каждого подзаголовка и framework.h для того, чтобы когда-либо использовать мой фреймворк, он работает нормально..

Я просто хотел бы включить основной заголовок во все мои sub.h, поэтому мне не нужно включать всю зависимость каждый раз.

Спасибо:)

6 ответов

Решение

В основном то, что вы делаете #include "A.h" в framework.h и #include "framework.h" в Ах Это вызывает циклическую зависимость файлов заголовков, и вы получите ошибки, такие как неопределенный класс А. Чтобы решить эту проблему, используйте предварительные объявления в файле заголовка и #include только в соответствующем файле cpp. Если это невозможно, я не вижу никакой другой опции, кроме включения отдельных заголовочных файлов.

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

Вместо этого сделайте следующее:

1) Сделайте предварительные определения всего, что вам нужно в соответствующих файлах подзаголовка.

2) Включить только необходимые файлы подзаголовка внутри файлов CPP.

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

Просто защитите основной заголовок с помощью include guard:

#ifndef FRAMEWORK_H
#   define FRAMEWORK_H
#   include <A.h>
#   include <B.h>
#   include <C.h>
#endif

Это предотвратит рекурсивное включение.

Я предполагаю, что у вас есть зависимость между - скажем, B и C такая, что B зависит от C, но в framework.h C включен после B.

Циркулярные включения, как правило, плохая идея в C++. Хотя защита заголовка не позволит препроцессору зайти в бесконечный цикл (или выдает ошибку из-за этого), вы получите неожиданные ошибки компилятора, потому что в какой-то момент файл заголовка не будет включен, если вы так думаете.

Вы должны включить A.h, B.h а также C.h от framework.h, И в A.h, не включайте framework.hпросто объявите классы, которые вы используете из него. Или сделайте это наоборот: включите framework.h от A.h, B.h а также C.h, и вперед объявлять классы в framework.h, И, конечно же, поместите каждый код, который потребует более подробных объявлений, чем, например, class A к файлам.cpp.

Я бы порекомендовал использовать #pragma один раз и поместить его в начало всех ваших заголовочных файлов (framework.h, Ah, Bh и Ch).

Хотя, если вы предпочитаете, я думаю, вы могли бы решить вашу проблему, просто добавив include guard в framework.h.

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