2012-04-03 77 views
2

在一个学术项目中,我试图建立一个简单的物理引擎。 我正在使用Eigen库进行向量/矩阵计算。 我想保留尽可能独立,因为我可以从图书馆/设计选择,以缓解未来的变化,所以我使用typedefs为特征类型。特征类型typedef C4430失败

文件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,并试图利用这些类型定义:

#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++不支持default-int。

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

在此先感谢。

回答

1

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

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

我收到很多错误C4430。

这样的描述真的让我烦恼。您的编译器不会因“错误C4430”而死亡,它会提供详细的错误信息,这对于找出问题的原因至关重要。如果没有人分享这些信息,你很难帮助你。你能不能请第一个完整的消息,以及导致错误的代码行?

错误的数量是不相关的,因为大多数错误很可能来自同一个问题。

由于微软警告 C4430写着“缺少类型说明符 - 假定为int”,我怀疑你是忘记包括艾根的头文件,使编译器不知道的Eigen::Vector2f是什么。

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


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

我怀疑是在编译RigidBody.cpp,编译器最终会解析在RigidBody.h类定义中的typedef前PhysicsEngine.h,让您的自定义类型定义不可在这一点上。

您应该删除RigidBody.h包括PhysicsEngine.h,或将您的typedefs移动到单独的头文件中。

+0

我没有添加其余的错误,因为我的Visual Studio版本是意大利语,我认为C4430足以让您了解问题。对不起,让你烦恼,我现在正在编辑我的帖子与消息翻译。 – 2012-04-03 08:21:00

+0

对不起,我没有发布所有包括。我现在做了。顺便说一句,所有工作正常,没有typedefs,使用特征类型。 – 2012-04-03 08:27:11

+0

@AndreaCasaccia:编译器仍然应该给你发生错误的文件名和行号,你能不能在那个地方发布代码? – 2012-04-03 08:48:32

1

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

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

  • 你必须写一个很多代码(也许有typedef库中的每一种类型)。
  • 即使你抽象用的vector3从实型(Eigen::Matrix3f)你没有得到一个真正的独立因为(与数学经营者除外),你会使用与该库中定义的函数原型(想,例如,如何在Eigen和Boost中定义单位矩阵)。
  • 要使用一个特定的数学库是不是一个微设计选择,它遍布所有的代码,你不能认为是独立的,很少有typedef。下一步会是什么?包装所有类以允许依赖注入?如果这是你所需要的,也许你应该从一个以这种方式设计的库开始(但我不认为它是常见的,甚至不是一个数学库的好主意)。
  • 隐藏重要详情。我知道你不想传播如果你的浮点数是单精度或双精度,但它很重要!舍入误差和精度是详细信息您在编写代码时必须注意。不应该使用typedef(但这是我的观点)来抽象代码或隐藏实现细节。我认为它应该仅用作快捷方式用于长型定义或在两个或多个等效定义之间切换。 floatdouble是不相同的(你必须总是想着你在做什么)。要在它们之间切换可以改变应用程序的结果,那么很好,你不能在typedef中做一些小的改动。

我在做什么错在这里?

当您未指定函数的返回类型(在VS2k5之前,缺省值为int与C中相同)时,会出现C4430错误。如果你声明了一个未知类型的变量,你可以得到这个错误。在你的情况下,你包含了你的头文件,但它可能不包括Eigen库中的全局矩阵类型定义(它在库的头文件Core中)。
编辑:您在您的PhysicsEngine.h中包含RigidBody.h,反之亦然,请将其解决(将您的typedef解压缩到另一个头文件中)并避免这种往返行为。

+0

我同意你的前三点。至于最后,用现代的IDE,一个简单的F12将不会揭示typedef的“真实”,所以我认为它并不真正“隐藏”细节。也就是说,我不能从我选择的矩阵类型中独立使用浮点数或实数,所以使用显式的特征类型将导致我使用明确的浮点数或双数我想。 – 2012-04-03 08:56:20

+0

正如我所说,我猜这个主题是完美的圣战! :)即使一个方法实现总是很容易检查,即使是一个简单的赋值操作也会导致一个细微的bug,那么我更愿意在我的代码中看到我在做什么。我认为typedef不应该被用来隐藏实现,而只是为了一个长声明提供**快捷键**。 – 2012-04-03 09:08:00

+0

如果我错了,请纠正我,但即使我无法从Eigen获得独立性,我至少可以独立于特定的本征类型,例如我可以在Eigen :: Matrix3f和Eigen :: Matrix3d之间切换。 – 2012-04-03 09:09:32