Search code examples
c++stdvectordelete-operator

Using delete on std::vector::back() before pop_back(), and using std::move() for new element


I have this function, but I'm not sure why I need to use delete m_gameStates.back() before using m_gameStates.pop_back() when I know that pop_back() destroys the element.

 //in header :
     std::vector<std::unique_ptr<GameState>> m_gameStates;
... 
...

void GameStateMechine::changeState(std::unique_ptr<GameState> pState)
{
    if(!m_gameStates.empty())
    {
        if(m_gameStates.back()->getStateID() == pState->getStateID())
        {
            return;
        }
        if(m_gameStates.back()->onExit())
        {
            delete m_gameStates.back();
            m_gameStates.pop_back();
        }
        m_gameStates.push_back(std::move(pState));
        m_gameStates.back()->onEnter();
    }
}

Is the delete operation unnecessary?

Also, for complex objects, is using std::move() (and not copy) the right thing to do always?

For example:

m_gameStates.push_back(std::move(pState));

UPDATE:

I have a lot of problems with using std::unique_ptr in std::vector. If I remove it and use raw pointers in the std::vector, do I need still to delete it?


Solution

  • The point of unique_ptr is to have one and only one owner for pointer and when its owner destroyed unique_ptr will delete pointer too. When you call m_gameStates.pop_back() it destroys last element that in turn is the owner of unique_ptr. Hence delete m_gameStates.back() not necessary and should not even compile.

    Your std::unique_ptr<GameState> pState argument belongs to function. If not std::move in m_gameStates.push_back(std::move(pState)) pState will be deleted at function's end so you moved its ownership to vector and that's correct.

    If you use raw pointer you must deleted it when you don't need it and remember not to use it after delete. If GameState instance owned at same time by only one owner std::move along with std::unique_ptr will be good idea. If you want GameState instance to be shared by multiple owners use std::shared_ptr.