2013-08-01 37 views
0

下面這個類正在導致可怕的錯誤量。這似乎很好,但。誰知道爲什麼VC++討厭我的任何C++專家?造成成千上萬錯誤的文件(C++)

Entity.h

#pragma once 
#include "World.h" 
#include "Renderer.h" 

class Entity { 
public: 
    Entity(World* world, Coordinate coord); 
    ~Entity(); 
    void render(Renderer renderer) const; 
    World* world; 
    Coordinate coord; 
}; 

Entity.cpp

#include "Entity.h" 

Entity::Entity(World* world, Coordinate coord) : world(world), coord(coord) { 
    world->entities.insert(this); 
} 

Entity::~Entity() { 
    world->entities.erase(this); 
} 

這些錯誤本身並不構成一個整體非常有意義,因爲他們甚至沒有與此相關的文件。一些常見的錯誤是文件意外結束,缺少';'在「{」和「實體不是類或名稱空間名稱」之前。當我在項目中不包含實體時,不會發生這些錯誤。這些錯誤中的最後一個出現在實體的聲明代碼中。

的錯誤(刪除所有重複):http://pastebin.com/TEMEhVZV

World.h

#pragma once 
#include <map> 
#include <vector> 
#include <unordered_set> 
#include "Chunk.h" 
#include "Coordinate.h" 
#include "Renderer.h" 

class World { 
public: 
    ~World(); 
    void generateChunk(Coordinate coord); 
    void loadChunk(Coordinate coord); 
    void renderWorld(Renderer* renderer); 
    std::unordered_set<Entity*> entities; 
    inline Chunk* getChunk(Coordinate coord) const { 
     return loadedChunks.at(coord); 
    } 
private: 
    std::map<Coordinate, Chunk*> loadedChunks; 
}; 

Renderer.h

#pragma once 
#include <SFML/Window.hpp> 
#include <SFML/OpenGL.hpp> 
#include "World.h" 

class Renderer { 
public: 
    sf::Window *window; 
    void bind(sf::Window* newWindow); 
    void initializeOpenGL(); 
    void renderChunk(Chunk* chunk); 
    inline void drawPoint(Coordinate coord) { 
     glBegin(GL_POINTS); 
     glVertex3d(coord.x, coord.y, coord.z); 
     glEnd(); 
    } 
private: 
    template <class T> 
    inline static void pushVector3(std::vector<T>* vertices, T x, T y, T z); 
}; 
+6

沒有看到的錯誤,沒有太多我們可以爲您做 – Mgetz

+1

世界應該是一個向前聲明,而不是包括(除非這是座標來自哪裏,這將是奇怪的)。沒有看到錯誤(至少向我們展示了第一對夫婦),這將很難提供幫助。 – crush

+2

聽起來像你可能在某處丟失某種結尾字符,如'}'或';'。這往往會導致一些荒謬的錯誤(通常是「意外的文件結束」),其中大部分幾乎毫無意義 – wlyles

回答

3

對我來說,它看起來像一個循環的頭文件依賴項,意思是無法定義的東西。

如果Renderer.h文件有作用於一個Entity對象的方法,幷包含這個頭文件作爲依賴,Entity將不得不宣佈前Renderer可以編譯。 (編譯器需要知道一個Entity對象有多大,所以它可以硬編碼堆棧偏移量。)

但是同樣,Renderer需要Entity。所以它也不能編譯!

之前可能沒有在您的項目中顯示過,因爲當'Entity'標題觸發它們時,頭文件的加載順序與現在不同。

所以,你應該做的就是修改頭文件,因此沒有循環依賴關係,然後只引用頭文件中的指針,因爲它們有固定的已知大小。這裏有一些技巧:

包括低層次的類而不是更高的類。

#include "World.h" 
--> 
#include "Coordinate.h" 
class World; 

使用指針。

#include "Renderer.h" 
void render(Renderer renderer) const; 
--> 
class Renderer; 
void render(Renderer* renderer) const; 

做這些,頭文件可以移動到您的.cpp文件:

#include "Entity.h" 
#include "World.h" 
#include "Renderer.h" 
+1

我同意這一點。我認爲它也是一個循環的頭文件依賴項,這是我在評論中得到的。如果你只是通過頭文件中的指針引用一個類,那麼你應該只轉發聲明該類,而不包含它的頭文件。 – crush

+0

不應該#pragma一旦解決這個問題?或者我是一個全面的noob,完全誤解了這一點? –

+0

嗯..重點是主要包含儘可能少的其他標題。 另一個問題可能是您從未將某個類def包含在另一個頭文件中,但由於它們編譯的順序不同,所以依賴類總是由此點定義的。 說類'a'包括'b'和'c','b'使用'c'。 – MST

0

很難給你太多幫助,沒有更多的上下文。根據我的經驗,這樣的錯誤幾乎總是與缺少分號有關。你給這些錯誤提供了一個文件和行號?我會檢查Renderer.h,並確保它不會丟失分號。

我建議這樣做的原因是,當你包含一個文件時,編譯器實際上會將它複製到這個文件中。這意味着以前文件中的拼寫錯誤可以在這些文件中體現出來。如果您可以發佈更多信息,或者自己複製並粘貼錯誤,我會盡力提供更多幫助。

編輯: 由於您發佈了錯誤,這更有意義。如果你看一下,在列表中的第一個錯誤實際上是數148.你需要向下滾動的錯誤編號1:

「錯誤1錯誤C2065:‘實體’:未聲明的標識符world.h」

對我來說,這看起來像你正在嘗試使用文件world.h中的類實體,它現在還不存在。所以這看起來像一個循環包含問題。

+0

只有當這兩個文件包含到項目中並引用時纔會出現錯誤。 –

+0

不應該#pragma一旦解決這個問題? –

+1

#pragma一次只確保文件包含一次。它不能確保它們包含在正確的順序中。看起來好像你正在試圖在定義它之前使用一個項目,等等。 – TylerLubeck

0

嘗試去第一個錯誤吐出來,並修復那個。在VC++雙擊中,應該將您帶到有問題的行。在第一次錯誤或第二次錯誤後,編譯器經常會如此無可奈何地困惑,以至於在其輸出中沒有其他值得關注。

我的懷疑是它會帶你到一個沒有顯示的頭文件中的一行。

+0

的最後評論中發佈的鏈接的副本第一個錯誤只是說「C1003:錯誤計數超過100;停止編譯」。所有背後的錯誤完全沒有意義。 –