0

I am new to using smart pointers and have only used unique_ptr so far. I am creating a game and I am using a vector of unique_ptr to store my game states.

Here is my vector code:

std::vector<std::unique_ptr<GameState>> gameStates;

Here is my question. Are the following functions going to work to control my vector:

void GameStateManager::popGameState(){
    if (getCurrentGameState() != nullptr)
        gameStates.pop_back();
}

void GameStateManager::pushGameState(GameState *gameState){
    gameStates.push_back(std::unique_ptr<GameState>(gameState));
}

GameState *GameStateManager::getCurrentGameState(){
    return gameStates.back().get();
}

My worries where that using raw pointers as arguments and to return the current game state would eliminate the point of using smart pointers. Is this a good way to do this?

4
  • 1
    Raw pointers are fine as long as they don't own memory, but do look into move semantics particularly for pushGameState. Commented Jun 18, 2014 at 11:00
  • 1
    That popGameState is weird. What does the if mean there? If you do not want to pop from an empty vector check that with if(!gameStates.empty()). Commented Jun 18, 2014 at 11:06
  • If someone does GameState g; gameStateManger.pushGameState(&g); things will break. To prevent that pushGameState should require a unique_ptr. Commented Jun 18, 2014 at 11:20
  • 1
    Is GameState polymorphic? If not, from its name, it sounds more like you want a std::vector<GameState>, with no pointers what so ever. Commented Jun 18, 2014 at 11:23

1 Answer 1

1

Try this:

void GameStateManager::pushGameState(std::unique_ptr<GameState> gameState){
    gameStates.push_back(std::move(gameState));
}

std::unique_ptr cannot be copied, but it can be moved.

I think it has some benefits.. For example, Look at this code.

std::unique_ptr<GameState> pgs;
...
gsm.pushGameState(pgs); // error!
gsm.pushGameState(std::move(pgs)); // you should explicitly move it

If you use raw pointers ...,

void GameStateManager::pushGameState(GameState *gameState) { ... }

{
    std::unique_ptr<GameState> pgs;
    ...
    gsm.pushGameState(pgs.get()); // IT'S NOT COMPILE ERROR! you can make some mistakes like this..
    gsm.pushGameState(pgs.release()); // you can use it, but I think you will make a mistake sometime, finally.
} // if you use `pgs.get()`, the `GameState` is deleted here, though `gameStates` still contains it.
Sign up to request clarification or add additional context in comments.

4 Comments

Thankyou for your suggestion could you please explain how this would work as I do not understand fully the use of the double reference.
You may want to read What is move semantics?
@DennisHarrop please see edit, which explain the benefit of use that. If you want to know about rvalue-reference, see William's link. (and please choose >o<)
I don't see a good reason for using an rvalue reference here. Why is it not just taken by value?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.