Several classes have a lot of non-trivial members within them, or don't
but likely should have the destructor defaulted in the cpp file for
future-proofing/being more friendly to forward declarations.
Leaving the destructor unspecified allows the compiler to inline the
destruction code all over the place, which is generally undesirable from
a code bloat perspective.
struct should be used when the data type is very simple or otherwise has
no invariants associated with it. Given these are used to form a
hierarchy, class should be used instead.