Вам необходимо включить foo.h
в bar.h
:
#pragma once
#include "foo.h"
class bar
{
bar(const foo & f);
};
Если вам нужно полное определение класса, которое вы используете, если вы не используете указатель (в этом случае будет достаточно предварительного объявления), вам нужно включить файл, в котором объявлен класс.
Почему иногда он компилируется, а иногда не получается?
Зависит от компилятора. Я предполагаю, что foo.h
включен в файл, который компилируется до достижения bar.h
. Так что bar.h
уже знает об определении foo
. Если сборка не удалась, файлы, которые были успешно скомпилированы, пропускаются и, возможно, foo.h
больше не включаются. Или, если вы внесете изменение только в x.cpp
, компилятор будет только строить этот файл и, возможно, пропустить включение foo.h
, которое было включено в файл, который уже скомпилирован.
Надеюсь, я был чист.
Почему того, что у вас уже есть, недостаточно?
Можно сказать, что
//Bar.cpp
#include "foo.h"
#include "bar.h"
// Bar's definitions
включает foo.h
до bar.h
. Действительно, но что, если bar.h
включен до foo.h
в другом месте? Вот почему хорошая идея включить foo.h в bar.h. Любой файл, включая bar.h, больше не должен включать foo.h
(что необходимо для компиляции), и имеет смысл включить в файл все, что вам нужно. Это не относится к предварительным объявлениям, но, опять же, вы используете полный тип, а не указатель.