我有三个类,其中两个依赖于彼此的功能,另一个包含指向并包含在两者中的指针:
播放器:
#pragma once
#include <SFML\Graphics.hpp>
#include "RenderableObject.h"
//#include "Renderer.h"
class Renderer;
class Player : public RenderableObject
{
public:
Player(int size, Renderer* renderer);
~Player();
void render();
void setX(int x);
void setY(int y);
int getX();
int getY();
void setVelX(float x);
void setVelY(float y);
float getVelx();
float getVely();
int getSize();
private:
int size;
int x;
int y;
float velx;
float vely;
Renderer* ren;
};
游戏管理:
#pragma once
#include "Player.h"
class Renderer;
class GameManager
{
public:
GameManager(Renderer* r);
~GameManager();
Player* getBall();
private:
Player* ball;
};
渲染器:
#pragma once
#include <SFML\Graphics.hpp>
#include "GameManager.h"
#include "Player.h"
class Renderer
{
public:
Renderer(GameManager* game);
~Renderer();
sf::RenderWindow* getWindow();
void draw();
void renderCircle(int size, int x, int y);
void renderSquare(int size, int x, int y);
private:
sf::RenderWindow* win;
GameManager* game;
Player* ball;
};
我怀疑这里存在某种循环依赖。通过添加&#34;类渲染器,我设法将60多个错误减少到3;&#34;到播放器头文件。但是,我现在正在接收&#34;使用未定义的类型&#34;错误。
可能有助于更高层次地了解我想要实现的目标:
GameManager对象应该包含一个实例(可能更多)的播放器。此GameManager对象在诸如Renderer之类的子系统之间共享,因此它们都可以访问相同的资源。
Renderer对象应该能够调用Player对象(从GameManager对象中检索)render()函数,而该函数又应该回调Renderer对象的renderCircle()对象。 / p>
我希望这是一个重新安排包含的简单案例,而不必重新设计我已经完成的工作。
答案 0 :(得分:2)
在头文件中,您只声明作为指针或引用的变量,所有编译器需要知道的是一个类存在,仅此而已。它不需要知道它有多大,或者班级有哪些成员。因此,通过前瞻声明就足够了。
但是,在使用变量的源文件中,创建了对象,并调用了成员函数,然后编译器需要完整的定义,这意味着您必须包含整个头文件。
使用您的代码,简化:
Player.h
#pragma once
class Renderer;
class Player
{
public:
Player(Renderer*);
private:
Renderer* ren;
};
GameManager.h
#pragma once
class Renderer;
class GameManager
{
public:
GameManager(Renderer*);
private:
Renderer* ren;
};
Renderer.h:
#pragma once
class Player;
class GameManager;
class Renderer
{
public:
Renderer(GameManager*);
private:
GameManager* game;
Player* ball;
};
上述头文件与您已有的头文件大致相同,但我在Renderer.h
中使用了前向声明。
现在Renderer.cpp
源文件,其中Player
和GameManager
对象实际上是创建而已使用,我们需要头文件中的完整定义:
#include "Renderer.h"
#include "Player.h"
#include "GameManager.h"
Renderer::Renderer(GameManager* game)
: game(game), ball(new Player)
{
}
// Other functions that calls member function in the `man` and `ball` objects
当然,您需要#include "Renderer.h"
和Player.cpp
源文件中的GameManager.cpp
。
如果你有其他错误,那是因为你做的其他事情,而不是因为循环依赖,因为那些已经用前向声明解决了。