简体   繁体   English

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

[英]Polymorphic C++ with Pure Virtual Function destructor

I am not sure if the following code is safe from memory leak. 我不确定以下代码是否可以防止内存泄漏。

#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

The above "interface" is been implemented by object3d.cpp. 上面的“接口”是由object3d.cpp实现的。 We may then add many Object3D objects into a Scene object if they belong to the same scene. 如果它们属于同一场景,则可以将许多Object3D对象添加到Scene对象中。 However, upon the end of the scene, I want to ensure there is no memory leak and so I would call delete on everything. 但是,在场景结束时,我想确保没有内存泄漏,因此我将对所有内容调用delete。 However, in the scene object, I have the following variable: 但是,在场景对象中,我具有以下变量:

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

As you can see, 如你看到的,

delete sceneObjects;
delete sceneTextures;
delete sceneMaterials;

should delete the QVector and according to Qt, it should call the destructor of those objects in it. 应该删除QVector并根据Qt调用其中的那些对象的析构函数。 However, Qt documentation were not clear about object POINTERS. 但是,Qt文档尚不清楚对象POINTERS。 Would Qt delete object pointers with their proper destructor? Qt会使用适当的析构函数删除对象指针吗? Additionally, what happens to Renderable pointers? 此外,可渲染指针会怎样? As you can see from the "interface" that it has no destructor. 从“接口”可以看到,它没有析构函数。

Thanks for any input. 感谢您的任何投入。 ChaoSXDemon ChaoSXDemon

First of all, your Renderable class must have a virtual destructor, because calling delete on a base pointer to a derived object is undefined behaviour without one. 首先,您的Renderable类必须具有虚拟析构函数,因为在指向派生对象的基本指针上调用delete是没有一个的未定义行为。

Second, no, you will need to loop through and call delete on each pointer (or, as Nikos noted , use qDeleteAll as long as every object in the container is allocated with plain new (and not new[] or malloc or anything else)) in each container to make sure their memory is reclaimed (how could Qt know if the pointers point to things allocated by new ? They could point to things allocated by new[] , things on the heap, the stack, or somewhere else). 其次,不,您将需要循环遍历并在每个指针上调用delete (或者, 如Nikos所指出的 ,只要容器中的每个对象都分配了普通new (而不是new[]malloc或其他任何东西),请使用qDeleteAll )以确保它们的内存被回收(Qt如何知道指针是否指向由new分配的对象?它们可以指向new[]分配的对象,堆,堆栈或其他地方的对象)。

If you don't want to do that, you can store unique_ptr s in the containers and then the destructors of the unique_ptr s will be called when you delete the containers, and those destructors will deallocate the memory they own. 如果您不想这样做,则可以在容器中存储unique_ptr ,然后在delete容器时将调用unique_ptr的析构函数,并且这些析构函数将释放其拥有的内存。 No need to manually deallocate them or use qDeleteAll . 无需手动释放它们或使用qDeleteAll

You need to delete each pointer manually. 您需要手动删除每个指针。 You don't need to iterate over every one manually though. 不过,您不需要手动遍历每个对象。 You can do this very easily with: 您可以使用以下方法轻松完成此操作:

qDeleteAll(*sceneObjects);
delete sceneObjects;

Same for your other containers. 其他容器也一样。 qDeleteAll is documented here: http://doc.qt.digia.com/qt/qtalgorithms.html#qDeleteAll-2 qDeleteAll记录在这里: http : qDeleteAll

Also add a virtual dtor, as Seth Carnegie mentioned. 如Seth Carnegie所述,还添加一个虚拟dtor。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM