What should be included and what can be forward declared in this header ?
class Polygon : public Shape { public: void setBasicCurve (const Bezier& curve); void magnify (Vector direction); void setPoints (const vector<Point*>& points); private: Plane* m_surface; std::list<Point*> m_points; Color m_color; Bezier& m_basic_curve; static Type m_shape_type; };Here are some practical tips to keep your header files lean.
Member Variables
The compiler should know the size of a Polygon object to create it. Therefore, it must have enough information to determine the size of each member variable:
Plane* m_surface; // 1 std::list<Point*> m_points; // 2 Color m_color; // 3 Bezier& m_basic_curve; // 4 static Type m_shape_type; // 5
Polygon derives from Shape. Hence, it consists of its own members plus Shape's members. Therefore the Shape's size needs to be known.
#include "shape.h"
1. m_surface is a pointer, therefore its size is known. We should only forward declare it
struct Plane;2. m_points is a std::list, and we can't know its size unless we know its structure and its contents. Therefore we include its declaration:
#include <list>m_points is a list of Point pointers, and all pointers have the same size. It's enough to declare that Point is a type:
struct Point;3. m_color is a Color, and we can't determine its size unless we know its structure. Therefore we include its declaration:
#include "color.h"4. m_basic_curve is a reference to a Bezier, and all references have the same size. It's enough to forward declare it:
struct Bezier;5. m_shape_type is a static variable, thus it is not a part of the object, and we don't care about its size. Thus we can simply forward declare it:
struct Type;
Member Functions
Compiler needs to have enough information that these are function definitions:
void setBasicCurve (const Bezier& curve); // 6 void magnify (Vector direction); // 7 void setPoints (const vector<Point*>& points); // 86. if Bezier is a type, then this is a function definition. Forward declare it
struct Bezier;
7. if Vector is a type, then this is a function definition. Forward declare it.
struct Vector;
8. it is not practically possible to forward declare the std::vector (or any other STL containers). Always choose to include the STL headers:
include <vector>
Here is the resulting header:
#include <list> #include <vector> #include "shape.h" #include "color.h" struct Bezier; struct Vector; struct Plane; struct Type; class Polygon : public Shape { public: void setBasicCurve (const Bezier& curve); void magnify (Vector direction); void setPoints (const vector<Point*>& points); private: Plane* m_surface; std::list<Point*> m_points; Color m_color; Bezier& m_basic_curve; static Type m_shape_type; };
Summary
These are the basic rules for inclusion- include the headers of classes you inherit from
- always include the headers of the STL containers
- forward declare the types of static variables
- forward declare the types of the variables held by reference or by pointer
- include the header of all variables held by value
- forward declare the function parameter types and the function return types
No comments:
Post a Comment