저는 Qt를 처음 접했고 메모리 관리와 객체의 수명에 대한 몇 가지 기본적인 사항이 궁금합니다. 개체를 언제 삭제 및 / 또는 파괴해야합니까? 자동으로 처리되는 것이 있습니까?
아래 예에서 내가 만든 개체 중 삭제해야하는 것은 무엇입니까? 인스턴스 변수 가 파괴 myOtherClass
되면 어떻게됩니까 myClass
? 객체를 전혀 삭제 (또는 파괴)하지 않으면 어떻게됩니까? 그게 기억에 문제가 될까요?
MyClass.h
class MyClass
{
public:
MyClass();
~MyClass();
MyOtherClass *myOtherClass;
};
MyClass.cpp
MyClass::MyClass() {
myOtherClass = new MyOtherClass();
MyOtherClass myOtherClass2;
QString myString = "Hello";
}
보시다시피 이것은 매우 초보자에게 쉬운 일이지만 쉽게 배울 수있는 곳은 어디입니까?
답변
QObject
s 를 사용하여 고유 한 계층을 구축하는 경우 , 즉 새로 생성 된 모든 항목을 초기화합니다.QObject
된 모든를 부모로 .
QObject* parent = new QObject();
QObject* child = new QObject(parent);
다음은 충분하다 의 때문에delete
parent
parent
의 소멸자가 파괴 처리됩니다 child
. (시그널을 발행하여 수행하므로 child
부모보다 먼저 수동으로 삭제해도 안전 합니다.)
먼저 자식을 삭제할 수도 있습니다. 순서는 중요하지 않습니다. 주문 이 수행 되는 예 중요한 여기 에 개체 트리에 대한 문서 입니다.
귀하의 MyClass
의 아이가 아닌 QObject
, 당신은 일을하는 일반 C ++ 방법을 사용해야합니다.
또한 QObject
s 의 부모-자식 계층 은 일반적으로 C ++ 클래스 계층 / 상속 트리의 계층과 독립적입니다. 즉, 할당 된 자식이 부모의 직접 하위 클래스 일 필요는 없습니다. . (하위 클래스) QObject
이면 충분합니다.
그러나 다른 이유로 생성자에 의해 부과 된 제약이있을 수 있습니다. 예 를 들어 가시성 플래그와 그런 식으로 몇 가지 기본 레이아웃을 수행하기 때문에 QWidget(QWidget* parent=0)
부모는 다른이어야합니다 QWidget
. 그러나 일반적으로 Qt의 계층 구조 시스템의 QObject
경우 부모로 사용할 수 있습니다 .
답변
Qt에서 소유권 개념이 매우 중요하다는 점을 지적함으로써 Debilski의 대답을 확장하고 싶습니다. 클래스 A가 클래스 B의 소유권을 가정하면 클래스 A가 삭제되면 클래스 B가 삭제됩니다. 개체를 만들고 상위를 지정할 때뿐만 아니라 한 개체가 다른 개체의 소유자가되는 여러 상황이 있습니다.
예를 들면 :
QVBoxLayout* layout = new QVBoxLayout;
QPushButton someButton = new QPushButton; // No owner specified.
layout->addWidget(someButton); // someButton still has no owner.
QWidget* widget = new QWidget;
widget->setLayout(layout); // someButton is "re-parented".
// widget now owns someButton.
다른 예시:
QMainWindow* window = new QMainWindow;
QWidget* widget = new QWidget; //widget has no owner
window->setCentralWidget(widget); //widget is now owned by window.
따라서 문서를 자주 확인하십시오. 일반적으로 메서드가 객체의 소유권에 영향을 미치는지 여부를 지정합니다.
Debilski에서 언급했듯이 이러한 규칙은 QObject에서 파생 된 객체에만 적용됩니다. 클래스가 QObject에서 파생되지 않으면 직접 파괴를 처리해야합니다.
답변
부모 (QObject 객체 또는 파생 클래스)에는 자식 (QObject / 파생 클래스)에 대한 포인터 목록이 있습니다. 부모가 파괴되는 동안 부모는 자식 목록의 모든 개체를 삭제합니다. QObject의이 속성을 사용하여 부모가 삭제 될 때마다 자식 개체가 자동으로 삭제되도록 할 수 있습니다. 다음 코드를 사용하여 관계를 설정할 수 있습니다.
QObject* parent = new QObject();
QObject* child = new QObject(parent);
delete parent;//all the child objects will get deleted when parent is deleted, child object which are deleted before the parent object is removed from the parent's child list so those destructor will not get called once again.
smartpointer를 사용하여 Qt에서 메모리를 관리하는 다른 방법이 있습니다. 다음 기사에서는 Qt의 다양한 스마트 포인터에 대해 설명합니다.
https://blog.qt.digia.com/blog/2009/08/25/count-with-me-how-many-smart-pointer-classes-does-qt-have/
답변
이러한 답변에 추가하려면 검증을 위해 Visual Leak Detetor
C ++를 기반으로하는 Qt 프로젝트를 포함하여 Visual C ++ 프로젝트에 라이브러리 를 활용하는 것이 좋습니다 .이 라이브러리는 new, delete, free and malloc
문과 호환되며 잘 문서화되어 있고 사용하기 쉽습니다. 자신의 인터페이스 클래스 QDialog
또는 QWidget
상속 된 인터페이스 클래스를 만든 다음이 클래스의 새 개체를 만들 때 개체의 setAttribute(Qt::WA_DeleteOnClose)
기능 을 실행하는 것을 잊지 마십시오 .