[완료] Qt에서의 메모리 할당/해제 메커니즘이 궁금합니다.
글쓴이: comkid / 작성시간: 일, 2008/05/04 - 5:01오후
질문이 좀 거창해졌는데요..
다른 것이 아니고 Qt Tutorial 4 - Let There Be Widgets 항목에 보면
MyWidget::MyWidget(QWidget *parent) : QWidget(parent) { setFixedSize(200, 120); QPushButton *quit = new QPushButton(tr("Quit"), this); quit->setGeometry(62, 40, 75, 30); quit->setFont(QFont("Times", 18, QFont::Bold)); connect(quit, SIGNAL(clicked()), qApp, SLOT(quit())); }
에서 quit에 대해 아래와 같이 설명이 나오는데요..
Quote:
Note that quit is a local variable in the constructor. MyWidget does not keep track of it; Qt does, and will automatically delete it when the MyWidget object is deleted. This is why MyWidget doesn't need a destructor. (On the other hand, there is no harm in deleting a child when you choose to. The child will automatically tell Qt about its imminent death.)
튜토리얼 볼 때는 스마트 포인터를 썼나 하고 그냥 그런가 보다 하고 넘어갔었는데요. 막상 제가 클래스 정의해서 하려니 정말 명시적으로 delete를 해주지 않아도 되는 것인가 하는 생각이 들어서요.
Qt의 메모리 할당/해제 메커니즘을 알면 답이 보일 것도 같은데 책이랑 문서랑도 봐도 (제가 키워드를 제대로 못 골라서인지) 제가 궁금한 부분에 대해서 알려주는 내용은 없어서요.
이런 고민을 하고 있는 이유는
QMainWindow를 상속받은 클래스를 정의하고 그 안에 제가 정의한 클래스(QObject를 상속받지 않은 C++ 클래스)에 대한 포인터를 멤버로 갖고 생성자에서 할당을 하려고 하는데 이런 경우에도 소멸자에 해제하는 루틴을 따로 만들지 않아도 알아서 해제가 되는 것인지..가 궁금해서요. 느낌 상(?) 그냥은 안될 것 같은데요. QObject를 상속한 클래스에 대해서만 자동으로 해제가 이루어지지 않나 막연히 추측하고 있는데..
저의 이런 궁금증을 속~ 시원하게 긁어 주실 분 안계신가요?
Forums:
생각하신대로 일단은
생각하신대로 일단은 QObject를 상속하지 않은 클래스는 자동 해제 대상에서 제외됩니다.
하지만 QObject를 상속받았으니까 무조건 자동 해제되는 건 아닙니다.
QObject를 상속받고, 부모 객체에 등록된 자식 객체가, 부모객체가 삭제될때 자동으로 삭제되는 것입니다.
여기서 말하는 부모는 상속관계에 있는 base 클래스와 derived 클래스를 말하는게 아니라 생성자에서 parent로 넘어간 포인터를 말합니다.
조금 더 자세한건 다음 글의 끝 부분에 적혀있습니다.
http://xylosper.net/112
디버깅 돌려보시면 소멸자에서 자식들을 해제하는 과정을 보실수도 있습니다.
추가 질문이 있는데요..
Colding Mice라는 샘플을 보면 QGraphicsItem에 대한 파생 클래스인 Mouse는 new로 생성할 때 따로 parent를 설정하지 않는데요. 이런 경우에는 어떤 식으로 해제가 되는 건가요?
예제 간혹 보다보면 new로 동적할당 하면서도 parent를 넘기지 않는 애들이 있는데 이런 경우는 그 객체가 add되는 녀석이 해제를 하는게 아닐까 하고 넘어갔는데 실제로도 그러한지는 잘 모르겠어서요.
그리고 제가 Qt는 처음 써봐서 mignw-g++, qt, vim으로 MS 윈도우 환경에서 프로그래밍 하고 있는데요.
어떤 식으로 디버깅 해볼 수 있는지 참고 할 수 있는 자료도 알려주시면 감사하겠습니다..^^;
Have a good day!
이런 경우는 좀
이런 경우는 좀 특별한 경우입니다.
assistant를 보시면 알겠지만 애시당초 QGraphicsItem는 QObject를 상속받은 클래스가 아닙니다.
특별하게 설계된 아이템 클래스들은 add된 곳에서 삭제됩니다.
말씀하신대로 이경우는 각 아이템은 그 아이템이 등록된 부모 아이템이나 최종적으로는 scene이 삭제할 책임을 가집니다.
이외에도 QListWidget/QTableWidget/QTreeWidget과 그 item클래스들도 마찬가지로 최종적으로 각 widget에 의해서 할당된 item들이 해제됩니다.
이것들을 해제하는 알고리즘은 어려운게 아닙니다.
예를 들어 QGraphicsScene의 소멸자는 다음과 같이 간단합니다.
보통은 문서에 나와있습니다만, 실제로 삭제되는지 궁금하다면 디버깅을 돌려보거나 위와같이 소스코드를 직접 찾아보면 되겠죠.
디버깅에 대해선, 전 항상 kdevelop이나 eclipse같은 IDE로밖에 안해봐서 직접 gdb등을 이용한 디버깅은 잘 모르겠네요.
Qt라고 특별히 다를 건 없는 것 같습니다. 중단점 찍고 스택보거나 출력함수로 직접 출력해보거나...
참고로 직접 출력할때는 qDebug()를 이용하면 간편합니다.
답변 감사합니다.
xylosper님 블로그도 갔었는데.. 링크해주신.. 부분은 왜 못 봤던 건지-_-;;
parent로 this가 넘어가는 걸 주의깊게 보질 않았었네요..
알려주신 내용으로 궁금한 부분은 해결되었습니다. 빠른 답변 감사합니다 :)
Have a good day!
댓글 달기