I don't understand why I get this compiler errors:
error C2027: use of undefined type 'GameState' note: see declaration of 'GameState' error C2338: can't delete an incomplete type warning C4150: deletion of pointer to incomplete type 'GameState'; no destructor called
This is the relevant code:
#pragma once
#include <SFML\Graphics.hpp>
#include "SpawnManager.h"
#include "Resource.h"
#include <stack>
#include <memory>
class GameState;
class Controller
{
public:
Controller();
void run();
void setPlayerScore(unsigned score);
sf::RenderWindow& getWindow() { return m_window; }
void addState(const States& state);
void changeState(const States& state);
GameState* getState() const;
void popState();
void add_state(const States& type, Controller * cont);
~Controller() {}
private:
SpawnManager<States, GameState> m_sFactory;
sf::RenderWindow m_window;
ScoreRecord m_playerScore;
std::stack<std::unique_ptr<GameState>> m_screens;
};
#pragma once
#include <SFML\Graphics.hpp>
#include <memory>
#include "Controller.h"
//State design pattern
class GameState
{
public:
explicit GameState(Controller* state_holder);
GameState(const GameState&) = delete;
GameState(GameState&&) = delete;
GameState& operator=(const GameState&) = delete;
GameState& operator=(GameState&&) = delete;
virtual ~GameState() = default;
virtual void displayState() = 0;
virtual void updateStage() = 0;
virtual void handleEvent(sf::Event& event) = 0;
protected:
std::unique_ptr<Controller> m_state;
};
Any ideas how to fix this?
The definition of the destructor of std::unique_ptr<T>
requires T
to be complete i.e. defined, not just declared. Since a std::unique_ptr<GameState>
is a(n indirect) member of Controller
, the definition of destructor ~Controller
requires the definition of the destructor of std::unique_ptr<GameState>
and therefore also the definition of GameState
, which was not provided.
Solution: Define GameState
before you define ~Controller
. A minimal example:
struct GameState;
// 1. Definition of Controller
struct Controller
{
~Controller();
std::stack<std::unique_ptr<GameState>> m_screens;
};
// 2. Definition of GameState
struct GameState
{
std::unique_ptr<Controller> m_state;
};
// 3. Definition of Controller::~Controller
Controller::~Controller(){} // or = default;
P.S. Consider that you can never have a GameState
be pointed by a Controller
that points to that same GameState
. In such situation you would end up with an infinite recursion of destructions of already destructed objects. And multiple GameStates
can not own the same Controller
and vice versa. Consider whether your ownership structure makes sense. I suspect that you need either shared ownership, or non-owning referral.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With