1

次のコードがメモリ リークから安全かどうかはわかりません。

#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は適切なデストラクタでオブジェクトポインタを削除しますか? さらに、Renderable ポインターはどうなりますか? 「インターフェース」からわかるように、デストラクタはありません。

ご意見ありがとうございます。ChaoSXデーモン

4

2 に答える 2

5

まず第一に、クラスには仮想デストラクタが必要です。これは、派生オブジェクトへのベース ポインタをRenderable呼び出すことは、仮想デストラクタがないと未定義の動作になるためです。delete

delete2番目に、いいえ、各コンテナでループして各ポインタを呼び出す必要があります(または、ニコスが指摘したように、コンテナ内のすべてのオブジェクトがプレーンで割り当てられているqDeleteAll限り使用します(またはその他のものではありません))。それらのメモリが再利用されます (ポインターがによって割り当てられたものを指しているかどうかを Qt がどのように知ることができますか? それらは、によって割り当てられたもの、ヒープ上のもの、スタック、または他の場所を指す可能性があります)。newnew[]mallocnewnew[]

それをしたくない場合はunique_ptr、コンテナに s を格納すると、コンテナのデストラクタunique_ptrが呼び出されdelete、それらのデストラクタが所有するメモリの割り当てを解除します。それらを手動で割り当て解除したり、使用したりする必要はありませんqDeleteAll

于 2012-10-25T21:48:29.130 に答える
2

各ポインタを手動で削除する必要があります。ただし、手動ですべてを繰り返す必要はありません。これは非常に簡単に行うことができます:

qDeleteAll(*sceneObjects);
delete sceneObjects;

他のコンテナについても同じです。qDeleteAllここに文書化されています:http://doc.qt.digia.com/qt/qtalgorithms.html#qDeleteAll-2

Seth Carnegie が述べたように、仮想 dtor も追加します。

于 2012-10-25T21:55:45.797 に答える