0

下面的这个类导致了大量的错误。不过看起来还不错。周围有任何 C++ 大师知道为什么 VC++ 讨厌我吗?

实体.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;
};

实体.cpp

#include "Entity.h"

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

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

这些错误本身并没有多大意义,因为它们甚至与此文件无关。一些常见错误是文件意外结束,缺少';' 在“{”和“实体不是类或命名空间名称”之前。当我的项目中不包含实体时,不会发生这些错误。最后一个错误出现在 Entity 的声明代码中。

错误(删除所有重复项): http: //pastebin.com/TEMEhVZV

世界.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;
};

渲染器.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);
};
4

3 回答 3

3

对我来说,它看起来像一个循环头依赖,这意味着无法定义一些东西。

如果您的 Renderer.h 文件具有作用于Entity对象的方法,并且包含此头文件作为依赖项,Entity则必须在Renderer编译之前声明。(编译器需要知道 Entity 对象有多大,这样它才能硬编码堆栈偏移量。)

但同样,Renderer需要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" 
于 2013-08-01T19:08:45.287 回答
0

如果没有更多的上下文,很难提供太多帮助。根据我的经验,像这样的错误几乎总是与缺少分号有关。您是否给出了包含这些错误的文件和行号?我会检查 Renderer.h,并确保它没有丢失分号。

我建议这样做的原因是,当您#include 一个文件时,编译器实际上会将其复制到该文件中。这意味着以前文件中的拼写错误会在这些文件中表现出来。如果您可以发布更多信息,甚至可以自己复制和粘贴错误,我会尽力提供更多帮助。

编辑:既然你已经发布了你的错误,这更有意义。如果您查看,列表中的第一个错误实际上是编号 148。您必须向下滚动以查看错误编号 1:

“错误 1 ​​错误 C2065:‘实体’:未声明的标识符 world.h”

对我来说,这看起来就像您正在尝试使用文件 world.h 中的实体类,但它还不存在。所以这看起来像一个循环包含问题。

于 2013-08-01T18:48:36.730 回答
0

尝试找到它吐出的第一个错误,然后修复那个错误。在 VC++ 中双击那里应该带你到有问题的行。很多时候,在出现一两个错误之后,编译器会感到非常困惑,以至于它的输出中没有其他东西值得一看。

我的怀疑是它会将您带到您未显示的那些头文件之一中的一行。

于 2013-08-01T18:56:22.467 回答