In Effective C++ (3rd edition), Scott Meyers, in Item 31, suggests that classes should have, on top of their classic Declaration (.h) and Definition (.cpp) files, a Forward Declaration Include File (fwd.h), which class that do not need the full definition can use, instead of forward declaring themselves.
I somewhat see the case for it, but I really don't see this as a viable option... It seems very hard to maintain, rather overkill and hardly necessary.
I can, however, see its use for template forward declarations, which are rather heavy. But for simple classes? It seems to be that it's a pain to maintain and will create a whole lot of almost empty include files that serve a very small purpose... is it worth the hassle?
Here's a example:
// Class.h
class Class
{
Class();
~Class();
};
// ClassFwd.h
class Class;
// Class.cpp
Class::Class()
{
}
Class::~Class()
{
}
My question:
What do you guys think? If this a good practice?
NOTE I am mostly interested in the arguments FOR this practice, to see if I missed something that would make me agree with Scott Meyers.
I used forward declaration header files for all my libraries. A library would typically have this structure:
lib/
include/
class headers + Fwd.h
src/
source files + internal headers
The lib/include
directory would contain all public classes headers along with one forward declarations header. This made the library light-weight on the include side. Any header outside of this library only includes the forward header (Fwd.h
), while sources outside of this library includes the necessary complete headers. One can also provide a convenience header (Lib.h
) that includes all the other headers, for use in source files.
Another thing to place in the forward declaration header is typedef
s for shared_ptr
, especially in the case of an inheritance hierarchy with factory classes that return pointers to implementations.
The above is useful for larger applications with lots of internal libraries. A refinement of the above for this case would be to place the public headers in lib/include/lib
. This way clients of your library would have to include lib/...
. Think of this as a namespace for your headers.
Good luck!
Placing a simple class Whatever;
in its own header has no advantages and lots of disadvantages.
Especially in the case where accessing a header can be time consuming, one uses simple forward declarations to avoid accessing headers; putting them in their own headers would defeat the purpose...
With templated things, as you note, it's a different matter. E.g. check out <iosfwd>
from the standard library.
Cheers & hth.
The practice allows the code user not to think about whether a class is regular or template. The user just #inludes "corresponding_fwd.h" file and has a class reference. One less annoyance for the user is A Good Thing. But if it's a small project or class' creator is the only class' user then it might be more annoyance. So, it depends.
If you have a large solution this is your only chance to handle the inherent dependencies:
struct A {
B* m_pB;
};
struct B {
A* m_pA;
};
Now A and B may reasonably be in different header files, maybe even different projects. Yet, their dependency is not some design defect but entirely logical and necessary. What do you do?
- First include a single Types.h forward-declarating header for eeach required project, i.e., the forward declaration does not have its own header file per class.
- Then include the Class.h of all required projects. These headers will require forward declarations to compile.
- Include the headers of the main project.
In a rather large solution (500k LOC) I've found this pattern to be very easily manageable. Otherwise, if you change a class declaration, where do you find all forward declarations that you may have made individually in any number of other header files?