Если определения классов для B
и C
фактически не ссылаются ни на один из членов класса Helper
, то компилятору не нужно видеть полное определение класса Helper
в их заголовочных файлах. Предварительного объявления класса Helper
достаточно.
Например, если определение класса B
использует только указатели или ссылки на Helper
, то рекомендуется прямая ссылка :
class Helper;
class B {
// <SNIP>
Helper* helper;
// <SNIP>
void help(const Helper& helper);
// <SNIP>
};
Если определение класса B
использует экземпляр класса Helper
(т. Е. Ему нужно знать размер экземпляра Helper
), или иначе относится к определению класса Helper
(в функциях шаблона, например.), тогда вам нужно сделать видимым полное определение класса Helper
(скорее всего, включив заголовочный файл, который определяет класс Helper
):
#include "helper.h"
class B {
// <SNIP>
Helper helper;
// <SNIP>
void help(Helper helper);
// <SNIP>
};
Правило того, когда использовать включения, а не предварительные объявления, относительно простое: использовать предварительные объявления, когда вы можете, и включает, когда вам нужно .
Преимущество этого очевидно: чем меньше у вас включений, тем меньше зависимостей между заголовочными файлами (и тем больше вы ускорите компиляцию).