2012-10-25 2 views
1

다음 코드가 메모리 누수로부터 안전한지 확실하지 않습니다.순수 가상 함수 소멸자가있는 다형성 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에 의해 구현되었습니다. 그런 다음 동일한 Scene에 속한 경우 많은 Object3D 객체를 Scene 객체에 추가 할 수 있습니다. 그러나 장면이 끝나면 메모리 누수가 없는지 확인하여 모든 항목에서 delete를 호출합니다. 그러나, 장면 객체에, 나는 다음과 같은 변수가 있습니다

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

당신이 볼 수 있듯이을

delete sceneObjects; 
delete sceneTextures; 
delete sceneMaterials; 

QVector와 Qt는에 따르면, 그 개체의 소멸자를 호출해야 삭제해야 그것. 그러나 Qt 문서는 객체 포인터에 대해 명확하지 않았습니다. Qt는 적절한 소멸자가있는 객체 포인터를 삭제합니까? 또한 Renderable 포인터는 어떻게됩니까? "인터페이스"에서 볼 수 있듯이 소멸자가 없습니다.

입력 해 주셔서 감사합니다. 파생 객체에 대한 기본 포인터에 delete를 호출하면 정의되지 않은 동작 하나하지 않고 있기 때문에 모든 ChaoSXDemon

답변

5

첫째, 당신의 Renderable 클래스는 가상 소멸자가 있어야합니다.

둘째, 아니, 당신은을 통해 루프를 필요로하고, as Nikos noted 각 포인터에 delete 전화 (또는 컨테이너의 모든 객체가 new 일반 (그리고 new[] 또는 malloc 또는 아무것도 할당 만큼 qDeleteAll를 사용 else))를 사용하여 메모리가 확보되었는지 확인하십시오. (포인터가 new에 의해 할당 된 것들을 가리키는 지 Qt가 어떻게 알 수 있습니까? new[]에 의해 할당 된 것들, 힙, 스택 또는 다른 곳에있는 것들을 가리킬 수 있습니다). 당신이 그렇게하지 않으려면

, 당신은 용기에 unique_ptr의를 저장할 수 있습니다 후 unique_ptr의의 소멸자는 때 delete 용기라는 것, 그 소멸자는 자신이 소유 한 메모리 할당을 해제합니다. 수동으로 할당을 해제하거나 qDeleteAll을 사용할 필요가 없습니다.

+0

그래서 소멸자도 순수 가상이어야합니다. – ChaoSXDemon

+0

@ChaoSXDemon은 순수 가상이 아니며 가상입니다. 순수하게 가상으로 만들 수는 있지만, 아무런 의미가 없기 때문에 어쨌든 정의가 있어야합니다. –

+0

Renderable을 사용하는 w/e 객체의 경우 올바른 소 거기를 호출하도록 구현 객체에 무엇을 써야합니까? – ChaoSXDemon

2

각 포인터를 수동으로 삭제해야합니다. 수동으로 모든 것을 반복 할 필요는 없습니다. 다음과 같이하면 쉽게 할 수 있습니다.

qDeleteAll(*sceneObjects); 
delete sceneObjects; 

다른 컨테이너와 동일합니다. qDeleteAll은 다음과 같이 문서화됩니다 : http://doc.qt.digia.com/qt/qtalgorithms.html#qDeleteAll-2

또한 언급 된 Seth Carnegie와 마찬가지로 가상 dtor를 추가하십시오.

+0

감사합니다. 올바르게 작동하고 있습니다. 그러나 QVector rItems는 내 항목을 찾을 수 없습니다.Renderable * o1 = new Object3D() 그리고 나중에 rItems.append (o1) 이후에 rItems.remove (rItems.indexOf (o1))를 호출하면 인덱스 배열이 바깥에 있음을 알 수 있습니다. 특히 반환 된 인덱스는 -1입니다. 어떤 아이디어? – ChaoSXDemon

+0

@ChaoSXDemon'indexOf()'는 요소를 찾을 수 없을 때 -1을 반환합니다. 그것은 "찾을 수 없다"고 말할 수있는 유일한 방법입니다. Qt는 예외 처리를 사용하지 않는다는 것을 기억하십시오. 반환 값을 인덱스로 사용하면 안됩니다. '<0'을 먼저 확인하십시오. –