我正在使用一个名为 Bullet 的物理库,但在阻止将 Bullet 标头包含到我的物理标头中时遇到了麻烦。
//Physics.h
#include <BulletPhysics/btBulletDynamicsCommon.h> // Contains lots of other headers
struct Physics
{
static btDiscreteDynamicsWorld* pDynamicsWorld;
static btAlignedObjectArray<btCollisionShape*> collisionShapes;
static vec3 findSomePoint();
};
现在在我的代码的其他各个部分中,我可能想要访问 Physics 结构,为此我需要包含 Physics 头文件,但这也将包括任何其他 CPP 文件中的所有库头文件。
我试图想办法让库头文件只包含在 Physics.cpp 中,但是如果我从 Physics.h 中删除头文件,我无法让编译器识别结构定义中的库类型。
对于一些成员,我可以只转发声明并且工作正常,但它不适用于非指针或引用类型,因为需要完整的定义。
我注意到,如果我使用命名空间,我可以将成员声明为 extern,并且不需要完整的类型定义。但它会导致与前向声明奇怪的事情:
struct btDiscreteDynamicsWorld; // This seems fine
template <typename T>
struct btAlignedObjectArray; // This works but seems really hacky and I'm not sure if it's even valid
namespace Physics
{
extern btDiscreteDynamicsWorld* pDynamicsWorld;
extern btAlignedObjectArray<btCollisionShape*> collisionShapes; // Complete type not needed
vec3 findSomePoint();
}
同样使用命名空间我失去了使用访问说明符的能力。
我还认为,我可以使用 getter 函数和返回引用,而不是让成员自己在结构中,但返回类型也至少需要一个前向声明(我认为不是完整类型),我仍然必须前向声明该模板键入我之前所做的方式。
最好的方法是什么?或者我是否过于强调防止复制额外的标题。一个标题包含许多其他标题,所以很多,所以我不确定我是否应该关心。