【问题标题】:How to prevent including header in header to minimise including in other CPPs如何防止在标头中包含标头以最大程度地减少包含在其他 CPP 中
【发布时间】: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 都将包含 &lt;vector&gt;。不,预处理器就像 10 年、20 年和 30 年前一样,是一个普通的愚蠢工具。然而,与包含战斗并不值得。打cpp其实比较好。

标签: c++ header definition code-separation


【解决方案1】:

这两个结构具有相似的含义,除了第二个允许您选择创建和初始化内存的位置。我个人不会太担心你项目的递归阅读器包含的线索很大。您实际上在这里使用全局变量来处理一些非常重要的共享状态,这通常表明您的设计中有一个流程。如果你的程序是多线程的并且无法绕过共享状态,

我建议使用第三种方法并在 getter 和 setter 中执行一些互斥(readers-waiter lock 似乎合适)在这种情况下,您需要以某种方式确保仅通过 setter 修改状态(可能通过返回一个来自 getter 的 const 引用。

如果您要坚持使用extern 解决方案并以非平凡的方式初始化这些对象(我认为不是),您还需要定义某种初始化函数并确保在任何事情之前调用它否则,在这种情况下,您可能应该考虑编写一个 Singleton 类,这就是我会做的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-04
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 2014-09-10
    • 2012-10-19
    • 1970-01-01
    相关资源
    最近更新 更多