Я новичок в C ++ и пытаюсь включить два .h файлов, которые я сделал. Включает в себя доступ друг к другу, поэтому в зависимости от того, в каком порядке я их включаю, происходит сбой или другой. Из-за этого я знаю, что единственная возможная проблема должна быть, когда я собираюсь скомпилировать «$ g ++ main.cpp foo1.cpp foo2.cpp», и он не может его прочитать. Я использовал #IFnDef, потому что видел, что это исправило проблему в другом посте, но это ничего не изменило для меня. Есть идеи?
Как вы уже видели, два заголовка не могут включать друг друга. Помните, что #include
Директива в основном означает «взять содержимое этого файла и сделать вид, что оно было вставлено прямо здесь». Если header1.h
говорит, чтобы включить содержимое header2.h
в начале, но header2.h
говорит, чтобы включить содержимое header1.h
в начале и header1.h
говорит (снова) включить header2.h
в начале … вы поняли идею.
#define
/#ifndef
трюк (называется «включить охрану«) позволяет избежать бесконечной рекурсии, позволяя включать каждый заголовок только один раз, но это означает, что компилятор будет видеть либо содержимое header1.h
с последующим содержанием header2.h
, или наоборот. Если код в каждом заголовке зависит от того, что определено в другом, то в любом случае вы получите код, ссылающийся на то, что не определено позже.
Вы можете избежать циклической зависимости, используя так называемое «предварительное объявление» — декларирование то, что не будет полностью определенный до позже Например:
// header1.h
#ifndef HEADER1_H
#define HEADER1_H
class Foo; // Declaration only
class Bar { // Definition
private:
// You can have a pointer to a type that's only declared, not defined.
Foo *p_foo;
// ...
};
#endif // ndef HEADER1_H
----
// header2.h
#ifndef HEADER2_H
#define HEADER2_H
#include "header1.h"
class Foo { // Definition
private:
// This requires class Bar to be defined, but that's OK, because it is.
Bar bar;
// ...
};
#endif // ndef HEADER2_H
В этом примере header1.h
не должен включать header2.h
потому что это не нужно определение класса Foo
только декларация. (Другими словами, компилятору нужно только знать, что класс Foo
существует; ему еще не нужно знать о своих членах.)
Других решений пока нет …