C ++ - 3个类之间的循环依赖

时间:2018-04-23 19:33:23

标签: c++ compiler-errors circular-dependency

我有三个类,其中两个依赖于彼此的功能,另一个包含指向并包含在两者中的指针:

播放器:

 #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>

我希望这是一个重新安排包含的简单案例,而不必重新设计我已经完成的工作。

1 个答案:

答案 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源文件,其中PlayerGameManager对象实际上是创建已使用,我们需要头文件中的完整定义:

#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

如果你有其他错误,那是因为你做的其他事情,而不是因为循环依赖,因为那些已经用前向声明解决了。