Это больше, чем просто избыточность, это потенциально проблематично.Скажем, Foo.h меняется, так что Foo становится typedef для какого-то конкретного экземпляра общего, шаблонизированного эквивалента - такого рода вещи, которые можно ожидать как часть нормальной эволюции программного обеспечения.Тогда «класс X» из Bar.cpp излишне вызовет ошибку компиляции ala:
--- fwd.h ---
template <typename T>
class XT
{
public:
int n_;
};
typedef XT<int> X;
--- fwd.cc ---
#include "fwd.h"
class X;
int main()
{
X x;
x.n_ = 0;
return x.n_;
}
--- compilation attempt ---
~/dev .../gcc/4.1.1/exec/bin/g++ fwd.cc -o fwd
fwd.cc:3: error: using typedef-name 'X' after 'class'
fwd.h:8: error: 'X' has a previous declaration here
Это одна из причин, по которой я всегда рекомендую использовать выделенные заголовки прямого объявления ala <iosfwd>
, поддерживаемые и включаемые основнойзаголовок для обеспечения постоянной согласованности.Я никогда не ставлю "класс X";в файле реализации, если там тоже не определен класс.Помните, что кажущиеся преимущества "класса X";Форвардные декларации не столько ограничивают #include
, сколько в том, что включаемые в них файлы могут быть большими и, в свою очередь, включать в себя множество других файлов: выделенные заголовки форвардных деклараций обычно в любом случае избегают подавляющего большинства.