【发布时间】:2018-06-15 01:19:26
【问题描述】:
我正在使用一个名为 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 函数和返回引用,而不是让成员自己在结构中,但返回类型也至少需要一个前向声明(我认为不是完整类型),我仍然需要前向以我之前所做的方式声明该模板类型。
最好的方法是什么?或者我是否过于强调防止复制额外的标题。一个标题包含许多其他标题,所以很多,所以我不确定我是否应该关心。
【问题讨论】:
-
不要为这样的事情而烦恼。现在的预处理器很聪明。
-
@Michael Walz 这听起来是个好消息。
-
@Michael Walz 每次我在类定义中包含 std::vector 时都会想到这一点,我一直认为
将包含在使用它的所有其他 cpp 中。很高兴听到这不值得担心。 -
是的,它包含在每个使用它的 cpp 中,但无需担心。
-
不,如果您在类定义中包含
::std::vector,那么使用它的所有其他 cpp 都将包含<vector>。不,预处理器就像 10 年、20 年和 30 年前一样,是一个普通的愚蠢工具。然而,与包含战斗并不值得。打cpp其实比较好。
标签: c++ header definition code-separation