我不确定以下代码是否可以防止内存泄漏。
#ifndef RENDERABLE_H
#define RENDERABLE_H
class QGLShaderProgram;
class GLWidget;
class BoundingBox;
class Renderable{
public:
virtual void update(float duration) = 0;
virtual void render(QGLShaderProgram& shader, float duration) = 0;
virtual BoundingBox* getBBox() const = 0;
virtual void translate(float xx, float yy, float zz) = 0;
virtual void rotate(float degrees_x, float degrees_y, float degrees_z) = 0;
virtual void scale(float xx, float yy, float zz) = 0;
};
#endif // RENDERABLE_H
上面的“接口”由object3d.cpp实现。然后,如果它们属于同一场景,我们可以将许多Object3D对象添加到Scene对象中。但是,在场景结束时,我想确保没有内存泄漏,因此我会在所有内容上调用delete。但是,在场景对象中,我有以下变量:
QVector<Renderable*>* sceneObjects;
QVector<GLTexture2D*>* sceneTextures;
QMap<QString, Material*>* sceneMaterials;
如您所见,
delete sceneObjects;
delete sceneTextures;
delete sceneMaterials;
应该删除QVector,根据Qt,它应该调用其中的那些对象的析构函数。但是,Qt文档并不清楚对象POINTERS。 Qt会用正确的析构函数删除对象指针吗?另外,可渲染指针会发生什么?正如您从“界面”中看到的那样,它没有析构函数。
感谢您的任何意见。 ChaoSXDemon
答案 0 :(得分:5)
首先,你的Renderable
类必须有一个虚析构函数,因为在一个指向派生对象的基指针上调用delete
是没有定义的未定义行为。
其次,不,您需要循环并在每个指针上调用delete
(或as Nikos noted,只要每个对象使用qDeleteAll
在容器中为每个容器分配了普通new
(而不是new[]
或malloc
或其他任何东西))以确保它们的内存被回收(如果指针指向Qt,Qt怎么知道由new
分配的东西?它们可以指向由new[]
分配的东西,堆上的东西,堆栈或其他地方。
如果您不想这样做,可以将unique_ptr
存储在容器中,然后在unique_ptr
容器时调用delete
的析构函数,那些析构函数将释放他们拥有的记忆。无需手动解除分配或使用qDeleteAll
。
答案 1 :(得分:2)
您需要手动删除每个指针。您不需要手动迭代每一个。您可以通过以下方式轻松完成此任务:
qDeleteAll(*sceneObjects);
delete sceneObjects;
与其他容器相同。此处记录了qDeleteAll
:http://doc.qt.digia.com/qt/qtalgorithms.html#qDeleteAll-2
也像Seth Carnegie所说的那样添加一个虚拟dtor。