If you want your build to be lightening fast, you need to think about compilation dependencies and try to minimize them as much as possible. This way, you need to re-compile as less files as possible when you have to change code.
If forward declaration comes into your mind, you are on the right track. But there are several things need to be mentioned.
- Never forward declare standard library classes. Unless you look into details of standard library, it’s very hard to tell if a “class” is actually a class, a typedef or a template class. Depending on these differences, the way you forward delcare things are different. A recommended way is always to include standard headers, never forward declare them. If standard library provides forward declaration headers like
iosfwd
, feel free to include that. - If you are libary provider, considring to provide
foofwd.h
headers for your clients to use just for declaration. Have definition of those classes separate infoo.h
. Of course keep them in sync.
When write definitions, make sure
- Avoid using objects when object references and pointers will do. You may define references and pointers to a type with only a declaration for the type. Defining objects of a type necessitates the presence of the type’s definition.
- Depend on class declarations instead of class definitions whenever you can. Note that you never need a class definition to declare a function using that class, not even if the function passes or returns the class type by value:
1
2
3
4
// defining) class Date
Date today(); // perfectly fine
void clearAppointments(Date d); // perfectly fine
Two techniques are going to greatly help us to achieve minimizing compilation dependencies. They are handle class(pimpl idiom
) and interface class.
Let’s use a example to illustrate both techniques. Considering writing following class
1 |
|
You need to include three header files if you write it naively.
If you use handle class, or pimpl idiom
, this class will look like following
1 |
|
Essencially you dedicated all implementation details to PersonImpl
class, so you can forward declare everything(except standard library) which class function needs, even if they are pass-by-value.
Noe let’s look at how to use interface class to achieve similar thing.
1 |
|
This achieved the same thing handle class gives us which is the ability to forward declare all dependencies.