我有 3 个类,其中 2 个相互依赖彼此的功能,一个包含指向并包含在两者中的指针:
玩家:
#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;
};
我怀疑这里存在某种循环依赖。通过添加“类渲染器”,我设法将 60 个奇数错误减少到 3 个;到播放器头文件。但是,我现在收到“使用未定义类型”错误。
这可能有助于更深入地了解我想要实现的目标:
GameManager 对象应该包含玩家的一个实例(也许更多)。此 GameManager 对象在 Renderer 等子系统之间共享,因此它们都可以访问相同的资源。
Renderer 对象应该能够调用 Player 对象(从 GameManager 对象中检索)的 render() 函数,后者又应该回调 Renderer 对象的 renderCircle() 对象。
我希望这是一个重新安排包含的简单案例,而不必重新设计我已经完成的工作。
最佳答案
在头文件中,您只声明指针或引用变量,编译器只需要知道一个类存在,仅此而已。它不需要知道它有多大,或者类(class)有哪些成员。因此,前向声明就足够了。
但是,在使用变量、创建对象和调用成员函数的源文件中,编译器需要完整的定义,这意味着您必须包含整个头文件。
简化您的代码:
播放器.h
#pragma once
class Renderer;
class Player
{
public:
Player(Renderer*);
private:
Renderer* ren;
};
游戏管理器.h
#pragma once
class Renderer;
class GameManager
{
public:
GameManager(Renderer*);
private:
Renderer* ren;
};
渲染器.h:
#pragma once
class Player;
class GameManager;
class Renderer
{
public:
Renderer(GameManager*);
private:
GameManager* game;
Player* ball;
};
除了我在 Renderer.h
中使用前向声明之外,上面的头文件与您已有的大致相同。
现在是 Renderer.cpp
源文件,其中 Player
和 GameManager
对象实际上是创建 和 < em>已使用,我们需要头文件中的完整定义:
#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
当然,你需要在Player.cpp
和GameManager.cpp
源文件中#include "Renderer.h"
。
如果你有其他错误,那是因为你做了其他事情,而不是因为循环依赖,因为这些已经通过前向声明解决了。
关于C++ - 3个类之间的循环依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49988660/