I'm trying to code a simple game, where the main.cpp
file instantiates the Game
class, and the Game
class instantiates the Player
class. I want the Player
class to have access to the Game
class' variables, so I guess the best way to do that is to have the Game
class pass itself to the Player
class:
game.h
#pragma once
#include <raylib.h>
#include "player.h"
class Game
{
public:
Game();
void run();
private:
void update();
void draw();
Player player;
};
game.cpp
#include "game.h"
Game::Game() : player(this, { 0, 0, 0 })
{
}
void Game::run()
{
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "teste");
SetTargetFPS(60);
while (!WindowShouldClose())
{
update();
draw();
}
CloseWindow();
}
void Game::update()
{
player.update();
}
void Game::draw()
{
BeginDrawing();
ClearBackground(RAYWHITE);
EndDrawing();
}
player.h
#pragma once
#include <raylib.h>
#include "game.h"
class Player
{
public:
Player(Game* game, Vector3 pos);
void update();
void draw();
Game* game;
Vector3 pos;
};
player.cpp
#include "player.h"
Player::Player(Game* game, Vector3 pos)
{
this->game = game;
this->pos = pos;
speed = .1;
}
void Player::update()
{
if (IsKeyDown(KEY_D)) pos.x = 1;
if (IsKeyDown(KEY_A)) pos.x = -1;
if (IsKeyDown(KEY_S)) pos.z = 1;
if (IsKeyDown(KEY_W)) pos.z = -1;
}
void Player::draw()
{
}
The code seems fine to Intellisense, but the compiler just throws a bunch of errors.
I tried passing this
as an argument to the Player
class constructor, but it didn't work out, as the compiler doesn't accept it.
CodePudding user response:
You have a circular dependency between your header files.
game.h
depends on player.h
, because the Game::player
member is a Player
instance, not a Player*
pointer or Player&
reference, so the complete Player
class declaration is needed. This is fine.
However, player.h
depends on game.h
, but Game
hasn't been declared yet (because of the header guard in game.h
) when the Player
class declaration is compiled.
Since the Player::game
member is just a Game*
pointer, you can use a forward declaration to break that header dependency, eg:
game.h
#pragma once
//#include <raylib.h> // <-- game.h doesn't use anything from this, so move it to game.cpp
#include "player.h" // <-- needed here because of Game::player
class Game
{
public:
Game();
void run();
private:
void update();
void draw();
Player player;
};
game.cpp
#include "game.h"
#include <raylib.h> // <-- move here
Game::Game() : player(this, { 0, 0, 0 })
{
}
...
player.h
#pragma once
#include <raylib.h> // <-- leave here if it declares Vector3
//#include "game.h" // <-- move to player.cpp
class Game; // <-- use this forward declaration instead
class Player
{
public:
Player(Game* game, Vector3 pos);
void update();
void draw();
Game* game;
Vector3 pos;
};
player.cpp
#include "player.h"
#include "game.h" // <-- move here
Player::Player(Game* game, Vector3 pos)
{
this->game = game;
...
}
...
In short, a header file should #include
only the things it actually uses directly. Anything else should be #include
'd in the .cpp
file instead. But, anything in a header file that is just a pointer or reference can be forward-declared without using an #include
. Keep your #include
s to a minimum in header files. The compilation process will be cleaner and more efficient because of it.