2012-04-03 78 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