Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 多态性++;使用纯虚函数析构函数_C++_Qt - Fatal编程技术网

C++ 多态性++;使用纯虚函数析构函数

C++ 多态性++;使用纯虚函数析构函数,c++,qt,C++,Qt,我不确定下面的代码是否可以防止内存泄漏 #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, f

我不确定下面的代码是否可以防止内存泄漏

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

QVector<Renderable*>* sceneObjects;
QVector<GLTexture2D*>* sceneTextures;
QMap<QString, Material*>* sceneMaterials;
应该删除QVector,根据Qt,它应该调用其中那些对象的析构函数。然而,Qt文档并不清楚对象指针。Qt会用适当的析构函数删除对象指针吗?此外,可渲染指针会发生什么情况?从“接口”可以看出,它没有析构函数

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

其次,不需要,您需要在每个指针上循环调用
delete
(或者,只要容器中的每个对象都分配了普通
new
(而不是
new[]
malloc
或任何其他内容),以确保它们的内存被回收(Qt如何知道指针是否指向由
new
分配的对象?它们可以指向由
new[]
分配的对象、堆上的对象、堆栈或其他地方)


如果您不想这样做,您可以将
unique_ptr
s存储在容器中,然后当您
delete
容器时,将调用
unique_ptr
s的析构函数,这些析构函数将解除分配它们所拥有的内存。无需手动解除分配它们或首先使用
qdeletall
总之,您的
Renderable
类必须有一个虚拟析构函数,因为在指向派生对象的基指针上调用
delete
是未定义的行为,没有虚拟析构函数

其次,不需要,您需要在每个指针上循环调用
delete
(或者,只要容器中的每个对象都分配了普通
new
(而不是
new[]
malloc
或任何其他内容),以确保它们的内存被回收(Qt如何知道指针是否指向由
new
分配的对象?它们可以指向由
new[]
分配的对象、堆上的对象、堆栈或其他地方)


如果您不想这样做,您可以将
unique_ptr
s存储在容器中,然后当您
delete
容器时,将调用
unique_ptr
s的析构函数,这些析构函数将释放它们拥有的内存。无需手动释放它们或使用所需的
qdeletall
手动删除每个指针。不过,您不需要手动迭代每个指针。您可以使用以下工具轻松完成此操作:

qDeleteAll(*sceneObjects);
delete sceneObjects;
其他容器也是如此。
qDeleteAll
记录在这里:


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

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

qDeleteAll(*sceneObjects);
delete sceneObjects;
其他容器也是如此。
qDeleteAll
记录在这里:


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

所以我猜析构函数也必须是纯虚拟的?@ChaoSXDemon不是纯虚拟的,只是虚拟的。你可以将它设为纯虚拟的,但这没有任何意义,而且它必须有一个定义。我应该在我的实现对象中写些什么,这样对于w/e对象,它就是using Renderable它将调用正确的析构函数?@ChaoSXDemon它将自动调用正确的析构函数,您不需要手动调用它们。但是您必须在
Renderable
中显式地编写一个虚拟析构函数,即使它是空的。所以我猜析构函数也必须是纯虚拟的?@ChaoSXDemon不是纯虚拟的,只是虚拟的.Y你可以让它成为纯虚拟的,但这没有任何意义,而且它必须有一个定义。我应该在我的实现对象中写些什么,这样对于使用Renderable的w/e对象,它将调用正确的析构函数?@ChaoSXDemon它将自动调用正确的析构函数,你不需要手动调用它们。但是y您必须在
Renderable
中显式地编写一个虚拟项目,即使它是空的。谢谢,它现在工作正常。但是,QVector rItems似乎找不到我的项目。假设我有:Renderable*o1=new Object3D(),稍后我调用(在rItems.append(o1)之后),rItems.remove(rItems.indexOf(o1))它给了我超出范围的索引数组。具体地说,返回的索引是-1。你知道为什么吗?@ChaoSXDemon
indexOf()
在找不到元素时返回-1。这是它告诉你“找不到”的唯一方法。(记住,Qt不使用异常处理。)您不应该仅仅将其返回值用作索引;首先检查
<0
。谢谢,它现在工作正常。但是,QVector rItems似乎无法找到我的项目。假设我有:Renderable*o1=new Object3D(),稍后我调用(在rItems.append(o1)之后),rItems.remove(rItems.indexOf(o1))它给了我超出范围的索引数组。具体地说,返回的索引是-1。你知道为什么吗?@ChaoSXDemon
indexOf()
在找不到元素时返回-1。这是它告诉你“找不到”的唯一方法。(记住,Qt不使用异常处理。)您不应该仅将其返回值用作索引;首先检查
<0