2013-08-01 61 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;停止编译”。所有背后的错误完全没有意义。 –