Home > Back-end >  Object pass itself to class constructor
Object pass itself to class constructor

Time:01-13

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 #includes to a minimum in header files. The compilation process will be cleaner and more efficient because of it.

  • Related