具有纯虚函数析构函数的多态C++



我不确定以下代码是否安全,不会发生内存泄漏。

#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 对象添加到场景对象中,如果它们属于同一场景。但是,在场景结束时,我想确保没有内存泄漏,所以我会对所有内容调用删除。但是,在场景对象中,我有以下变量:

QVector<Renderable*>* sceneObjects;
QVector<GLTexture2D*>* sceneTextures;
QMap<QString, Material*>* sceneMaterials;

如您所见,

delete sceneObjects;
delete sceneTextures;
delete sceneMaterials;

应该删除 QVector 并根据 Qt,它应该调用其中这些对象的析构函数。然而,Qt文档对对象指针并不明确。Qt会使用正确的析构函数删除对象指针吗?此外,可渲染指针会发生什么情况?从"接口"中可以看出,它没有析构函数。

感谢您的任何输入。 ChaoSXDemon

首先,Renderable类必须有一个虚拟析构函数,因为在指向派生对象的基指针上调用delete是没有虚拟析构函数的未定义行为。

其次,不,你需要遍历并调用每个指针上的delete(或者,正如 Nikos 指出的那样,只要容器中的每个对象都分配了纯new(而不是new[]malloc或其他任何东西)),就使用qDeleteAll在每个容器中确保它们的内存被回收(Qt 怎么知道指针是否指向new分配的东西?他们可以指向new[]分配的东西,堆上的东西,堆栈上的东西,或者其他地方)。

如果您不想这样做,可以将unique_ptr存储在容器中,然后在delete容器时调用unique_ptr的析构函数,这些析构函数将释放它们拥有的内存。无需手动释放它们或使用qDeleteAll

您需要手动删除每个指针。不过,您不需要手动迭代每一个。您可以使用以下方法轻松完成此操作:

qDeleteAll(*sceneObjects);
delete sceneObjects;

其他容器也是如此。qDeleteAll记录在这里:http://doc.qt.digia.com/qt/qtalgorithms.html#qDeleteAll-2

还要添加一个虚拟 dtor,正如 Seth Carnegie 提到的。

最新更新