For a C++ program to use a C++ class, it requires the declaration. If the class inherits from base classes, then those declarations are required to process that class declaration. This applies recursively: the entire inheritance tree of the class is required.
If the inheritance graph is so deep and broad (perhaps due to multiple inheritance) that the project decides it is unacceptable, then it has to be restructured. Classes might be able to use aggregation instead of inheritance. So that is to say, instead of:
#include <widget.h>
class foo : public widget { ... };
it may be possible to have;
class widget; // "forward" declaration only; no #include needed
class foo { widget *pwidget; ...}
Now, only the file which implements foo
needs the full declaration of widget
; the clients of foo
which are including "foo.h"
don't need it.
But now foo
is not a-kind-of widget
any longer, which has implications on the code organization. foo
still has the widget
parts by way of creating an object and holding it. If widget
conforms to some abstract interface for widgets, foo
may be able to implement that, and delegate to the contained widget
.
Another tool in minimizing dependencies is dependency inversion.