2

在一个学术项目中,我正在尝试设置一个简单的物理引擎。我正在使用 Eigen 库进行向量/矩阵计算。我想尽可能地独立于我正在做的库/设计选择,以简化未来的变化,所以我将 typedefs 用于 Eigen 类型。

文件 PhysicsEngine.h

#pragma once

#include <Eigen/Core>
#include <Eigen/Geometry>
#include "RigidBody.h"

... other inclusions ...

namespace PhysicsEngine
{
    typedef float real;
    typedef Eigen::Vector3f vector3;
    typedef Eigen::Quaternionf quaternion;
    typedef Eigen::Matrix4f matrix4;
    typedef Eigen::Matrix3f matrix3;

    ...

1)这是一个好的设计选择还是我误解了老师告诉我们的内容?

包括上面的文件,在 RigidBody.h 中,并尝试使用这些 typedef:

#pragma once

#include "PhysicsEngine.h"

namespace PhysicsEngine
{
    class RigidBody
    {
    public:
    vector3 position;               // <- error C4430
    real inverseMass;               // <- error C4430
    vector3 velocity;               // <- error C4430
    vector3 netForce;               // <- error C4430

    quaternion orientation;         // <- error C4430
    matrix3 inverseInertiaTensor;   // <- error C4430
    vector3 rotation;               // <- error C4430
    vector3 netTorque;              // <- error C4430

    matrix4 transformationMatrix;   // <- error C4430
    ...

我得到:

错误 C4430:缺少类型说明符 - 假定为 int。注意:C++ 不支持默认整数。

2)我在这里做错了什么?

提前致谢。

4

2 回答 2

1

这是一个好的设计选择还是我误解了老师告诉我们的内容?

这可能是一个糟糕的设计选择,因为您隐藏了您正在使用 Eigen 类型的事实,但是您需要知道这个事实才能使用您的 typedef。

我收到很多错误 C4430。

这样的描述真的让我很生气。您的编译器不仅会因“错误 C4430”而死机,它还会为您提供详细的错误信息,这对于找出问题的原因至关重要。不分享这些信息会让任何人都难以帮助你。您能否发布第一条完整的消息以及导致错误的代码行?

错误的数量无关紧要,因为大多数错误很可能源自同一个问题。

由于 Microsoft的警告C4430 读取“缺少类型说明符 - 假定为 int”,我怀疑您忘记包含 Eigen 头文件,因此编译器不知道 anEigen::Vector2f是什么。

尝试添加#include <Eigen/Core>PhysicsEngine.h.


从您更新的代码中:您有循环依赖项。 PhysicsEngine.h包括RigidBody.h,反之亦然。不是很好。

我怀疑在编译RigidBody.cpp时,编译器最终会在RigidBody.htypedefs in 之前解析类定义PhysicsEngine.h,因此此时您的自定义 typedefs 不可用。

您可能应该RigidBody.h从 中删除包含PhysicsEngine.h,或者将您的 typedef 移动到单独的头文件中。

于 2012-04-03T08:13:23.357 回答
1

这是一个好的设计选择还是我误解了老师告诉我们的内容?

我想你会得到很多不同的意见。在我看来,这不是一个很好的选择(有一些例外)。我试图解释为什么。

  • 您将不得不编写大量代码(可能typedef为库中的每种类型编写一个代码)。
  • 即使你vector3真实类型(_在 Eigen 和 Boost 中)。Eigen::Matrix3f
  • 使用特定的数学库不是微设计的选择,它遍及您的所有代码,您不能认为只有少数typedef. 下一步会是什么?包装所有类以允许依赖注入?如果这是您需要的,也许您应该从以这种方式设计的库开始(但我认为这对于数学库来说并不常见,甚至不是一个好主意)。
  • 隐藏了重要的 细节。我知道如果您的浮点数是单精度或双精度,您不想传播,但这很重要!舍入误差和精度是您在编写代码时必须注意的细节。typedef不应该使用(但我认为)来抽象您的代码或隐藏实现细节。我认为它应该仅用作长类型定义的快捷方式或在两个或多个等效定义之间切换。float并且double不等效(并且您必须始终考虑自己在用它们做什么)。在它们之间切换可以改变应用程序结果,那么你不能通过typedef.

我在这里做错了什么?

当您未指定函数的返回类型时会出现 C4430 错误(在 VS2k5 之前,默认值int与 C 中相同)。如果您声明一个未知类型的变量,您可能会收到该错误。在您的情况下,您包含了头文件,但它可能不包含Eigen 库中的全局矩阵类型定义Core(它位于库的头文件中)。
已编辑:您包含RigidBody.h在您PhysicsEngine.h的文件中,反之亦然,将其修复(typedef如果您想使用它们,请提取您的文件)到另一个头文件并避免这种往返。

于 2012-04-03T08:37:21.327 回答