Search code examples
c++vectormultiple-inheritanceerase

erasing from a vector with a base class ptr


I have a class called Circle used in a physics simulation.

A circle is declared as follows:

class Circle : public IPhysics,
               public IRenderable
{
...
}

The circles are created, then stored in a vector using their IRenderable pointer like so:

Circle* pC = new Circle( 
        mass,
        vec2( vCircles[x]._x, vCircles[x]._y ),     // position
        vec2(0.0f, 0.0f),                           // velocity
        vec2(0.0f, -g_kGRAVITY),                    // acceleration
        _ClientCfg.rGridSquareSideLen * 0.1f,       // radius
        colour, colour                              // colour, motion colour
    );

    if( pC != nullptr )
        streamed_circles.push_back(dynamic_cast<IRenderable*>(pC)); 

After they've been rendered, they're deleted from the back buffer like so:

std::vector<IRenderable*> _pbkBuffer;
...
_pBkBuffer->erase( _pBkBuffer->begin(), _pBkBuffer->end() );

This delete is causing memory leaks.

In order to erase objects from the back buffer vector, will I first have to cast them back to their leaf class types (e.g. Circle type or other leaf class type?)

edit: I'm thinking that I'd need something like this:

std::for_each(
    _pBkBuffer->begin() + _nStaticRenderables, _pBkBuffer->end(),
    []( IRenderable* p )
    {
        if( typeid(*p) == typeid(Circle) )
        {
            Circle* pC = dynamic_cast<Circle*>(p);
            delete pC;
        }
    }
);

thanks


Solution

  • You don't have to cast them back to Circle * (assuming the destructor of IRenderable is virtual). But you do need to call delete on each pointer in the vector before calling vector::erase.

    A much, much better option is to change std::vector<IRenderable*> _pbkBuffer; to std::vector<std::unique_ptr<IRenderable>> _pbkBuffer;. Now calling erase should not leak any memory.


    Note:

    streamed_circles.push_back(dynamic_cast<IRenderable*>(pC)); 
    

    The dynamic_cast above is unnecessary; pC is implicitly convertible to IRenderable *.