从具有基类ptr的向量中删除

时间:2013-05-01 22:18:19

标签: c++ vector multiple-inheritance erase

我在物理模拟中使用了一个名为Circle的类。

圆圈声明如下:

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

创建圆圈,然后使用IRenderable指针将其存储在矢量中,如下所示:

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)); 

渲染完成后,它们会从后缓冲区中删除,如下所示:

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

此删除导致内存泄漏。

为了从后缓冲区向量中擦除对象,我是否首先必须将它们转换回它们的叶类类型(例如Circle类型或其他叶类类型?)

编辑: 我想我需要这样的东西:

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

感谢

2 个答案:

答案 0 :(得分:3)

您不必将它们强制转换回Circle *(假设IRenderable的析构函数为virtual)。但在调用delete之前,您需要在vector的每个指针上调用vector::erase

更好,更好的选择是将std::vector<IRenderable*> _pbkBuffer;更改为std::vector<std::unique_ptr<IRenderable>> _pbkBuffer;。现在调用erase不应泄漏任何内存。


注意:

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

上面的dynamic_cast是不必要的; pC可隐式转换为IRenderable *

答案 1 :(得分:1)

你需要在你的项目上调用delete,然后才能从向量中删除它们,否则你将失去对它们的引用但不会删除内存,因为vector只管理其内部表示的内存(它会调用IRenderable*的析构函数,它什么都不做。)

std::vector<IRenderable*> _pbkBuffer;

for (size_t i = 0; i < _pbkBuffer.size(); i++) {
    delete _pbkBuffer[i];
}
_pbkBuffer.clear();

您需要确保IRenderable的析构函数为virtual,否则delete将无效。

将元素添加到dynamic_cast<IRenderable*>(pC)时,您不需要vector。您只需要dynamic_cast向下转换类型系统(从类到继承类),而不是向上(从类到其基类)。