0

我有一个名为 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() );

此删除导致内存泄漏。

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

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

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

谢谢

4

2 回答 2

3

您不必将它们强制转换回(假设isCircle *的析构函数)。但是您确实需要在调用之前调用每个指针。IRenderablevirtualdeletevectorvector::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 *.

于 2013-05-01T22:26:25.013 回答
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在类型系统中向下转换(从类到继承类),而不需要向上转换(从类到其基类)。

于 2013-05-01T22:25:24.837 回答