Skip to main content
added 690 characters in body
Source Link
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;
}
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;
};
class GameState;
class Game;

class GameStateMachine
{
    std::vector<std::shared_ptr<GameState>>mvGameStates;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::shared_ptr<GameState>unique_ptr<GameState> pState);
    void changeState(std::shared_ptr<GameState>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 if i change the vector of GameState shared_ptr of GameStateMachine to unique_ptr 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?

class GameState
{
 public:
    GameState(){}
    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;
}
class gGameStateSplash : public GameState
{
    static bool firstSplash;
    int msplashID;
    uint32_t splashStart;
public:
    gGameStateSplash     () :GameState(), msplashID(SPLASH), splashStart(0) {}
    ~gGameStateSplash    ()                                                 {}

    int getStateID       ()const override { return msplashID; }

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

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

   void shutDown         ()override;
};
class GameState;
class Game;

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

public:
    GameStateMachine():mvGameStates(){}
   ~GameStateMachine(){}

    void pushState(std::shared_ptr<GameState> pState);
    void changeState(std::shared_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 if i change the vector of GameState shared_ptr of GameStateMachine to unique_ptr 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?

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;
}
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;
};
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?

Source Link

Unique_ptr game state vs shared_ptr game state

I have this (typical) base class:

class GameState
{
 public:
    GameState(){}
    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    ()                                                 {}

    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::shared_ptr<GameState>>mvGameStates;

public:
    GameStateMachine():mvGameStates(){}
   ~GameStateMachine(){}

    void pushState(std::shared_ptr<GameState> pState);
    void changeState(std::shared_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 if i change the vector of GameState shared_ptr of GameStateMachine to unique_ptr 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?