1
\$\begingroup\$

I have this (typical) base class:

class GameState
{
 public:
    GameState(){}
    GameState(GameState&& other) = default;
    GameState& operator=(GameState&& other) = default;
    virtual ~GameState() {}

    virtual int getStateID         ()const = 0;

    virtual bool onEnter           ()      = 0;
    virtual bool onExit            ()      = 0;

    virtual void update (Game& game)       = 0;
    virtual void draw              ()      = 0;

    virtual void shutDown          ()      = 0;
}

And this is a state inherited from GameState base class:

class gGameStateSplash : public GameState
{
    static bool firstSplash;
    int msplashID;
    uint32_t splashStart;
public:
    gGameStateSplash     () :GameState(), msplashID(SPLASH), splashStart(0) {}
    gGameStateSplash(gGameStateSplash&& other)
    {
        firstSplash = std::move(other.firstSplash);
        msplashID   = std::move(other.msplashID);
        splashStart = std::move(other.splashStart);
    }

    gGameStateSplash& operator=(gGameStateSplash&& other)
    {
        firstSplash = other.firstSplash;
        msplashID   = other.msplashID;
        splashStart = other.splashStart;
        return *this;
    }
    ~gGameStateSplash    ()                                                 {}

    int getStateID       ()const override { return msplashID; }

    bool onEnter         ()override;
    bool onExit          ()override;

    void update(Game& game)override;
    void draw            ()override;

   void shutDown         ()override;
};

And this 'GameStateMachine' which use states inherited from GameState:

class GameState;
class Game;

class GameStateMachine
{
    std::vector<std::unique_ptr<GameState>>mvGameStates;

public:
    GameStateMachine():mvGameStates(){}
    GameStateMachine(GameStateMachine&& other){ mvGameStates = std::move(other.mvGameStates);}
    GameStateMachine& operator=(GameStateMachine&& other) { mvGameStates = std::move(other.mvGameStates);  return *this; }
   ~GameStateMachine(){}

    void pushState(std::unique_ptr<GameState> pState);
    void changeState(std::unique_ptr<GameState> pState);
    void popState();

    void update(Game& game);
    void render();
    void cleanAndExit();
};

And instance of GameStatesMachine is used by Game class to update game. As you can see neither GameStates nor GameStatesMachine has members too fancy, just a couple of integers and some boolean. I use VS 2019 and the program does not compile and throws compilation error c2280 pointing to the GameStates vector of GameStateMachine. I have read Microsoft documentation about it as well as several posts in StackExchange. As read, unique_ptr can not be copied and a move constructor must be implemented in order to do it and to avoid the compiler generates one itself and mark it as delete. So i have implemented move constructor in GameState base class and all inherited states classes. Nothing works. I implemented move constructor also in GameStateMachine with the same result. But if i change unique_ptr to shared_ptr the error vanishes and all compiles and works as expected. I want to use unique_ptr because i think the states are going to be owned only by Gameclass, so why waste memory using a shared_ptr?. Am i wrong?

\$\endgroup\$
  • \$\begingroup\$ If you need help with the errors your std::unique_ptr usage generates, that's the version of the code you should share. \$\endgroup\$ – Tyyppi_77 Feb 1 at 10:22
  • \$\begingroup\$ @Tyyppi_77 thanks for the advice :). Done it. \$\endgroup\$ – Battyhal Feb 1 at 10:50
  • \$\begingroup\$ And what's the specific compiler error and where does that happen? \$\endgroup\$ – Tyyppi_77 Feb 1 at 11:05
  • \$\begingroup\$ The error is : C++ Compiler Error C2280 "attempting to reference a deleted function" and also prints this as a message : See the reference to the creation of a template class instance "std :: vector <std :: unique_ptr <GameState, std :: default_delete <GameState>>, std :: allocator <std :: unique_ptr <GameState> \$\endgroup\$ – Battyhal Feb 1 at 11:10
  • 2
    \$\begingroup\$ Try to put the definition of your destructors in the cpp instead of the header... \$\endgroup\$ – Vaillancourt Feb 1 at 11:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.