I am writing a static library for C/C++ (personal project). As my headers became rather large, I thought that splitting my headers would be a good idea.
Right now a header looks like this:
MainClass.hpp:
- namespace impl: implementation details enclosed in a namespace
impl - forward declarations of classes declared below (when needed)
MainClassdeclarationMainClassfree functions declarationsMainClassspecialization declarationMainClassspecialization free function declarationsAuxiliaryClass1declarationAuxiliaryClass1free functions declarations- …
AuxiliaryClassNdeclarationAuxiliaryClassNfree functions declarationsMainClassdefinitionMainClassfree functions definitionsMainClassspecialization definitionMainClassspecialization free function definitionAuxiliaryClass1definitionAuxiliaryClass1free functions definitions- …
AuxiliaryClassNdefinitionAuxiliaryClassNfree functions definitions
- namespace impl: implementation details enclosed in a namespace
Where:
AuxiliaryClassKis a class logically or structurally related toMainClass(e.g. an iterator forMainClass, a nested class withinMainClass, a derived class ofMainClassetc.)ClassXfree functions as recommended in How Non-Member Functions Improve Encapsulation and Monoliths "Unstrung"- definitions are in header because they are templates.
This is becoming very crowded and difficult for me to navigate so I thought that splitting across multiple headers would help. However I do not know how to do it right.
Here is how I think the structure could look like:
MainClass.hpp:
- forward declarations (when needed)
- small classes/structs definitions & declarations
#includethe other headers
_Class.hpp:
_Classdeclaration_Classfree functions declarations
- _Class.inl:
_Classdefinition_Classfree functions definitions
With a _Class for each: MainClass, MainClass specialization, AuxiliaryClassK.
My questions are:
- Is it reasonable to want to split a header (all are functionalities of
MainClass) (I have headers over 1000 lines long and I foresee even longer ones) or should I leave it as it is? - Is the above split scheme ok? Should I further split a class and the free functions related to that class? Are there other solutions to make the code more maintainable?
- How to hide the other headers (not in a sense of obfuscating / making the code unavailable, but avoid exposing the headers the users see (e.g. in a GUI with autocomplete)? They should include and be aware only of
MainClass.hpp. Seeing other headers without being clear that they are behind–the–scenes headers will produce unnecessary confusion. One idea is to add a prefix like an_(underscore) or to put them in aimplfolder. (Again, this is not about hiding classes (I do that with a namespace), but to hide the split behind a header they should use).