2016. 4. 13. 11:44

Object Trees & Ownership (객체 트리들과 소유권)

Object Trees & Ownership

객체 트리들과 소유권

Overview

요약

QObjects organize themselves in object trees. When you create a QObject with another object as parent, it's added to the parent's children() list, and is deleted when the parent is. It turns out that this approach fits the needs of GUI objects very well. For example, a QShortcut (keyboard shortcut) is a child of the relevant window, so when the user closes that window, the shortcut is deleted too.

QObject 들은 스스로를 객체 트리들로 구성합니다. 만약 당신이 다른 객체를 부모로 지정하여 QObject 를 생성할 때, 이 객체는 다른 객체의 children() 목록에 추가되고, 부모가 제거 될 때 같이 제거 됩니다. 이것은 GUI 객체들의 요구사항에 아주 적합합니다. 예를 들어 QShortcut (키보드 바로가기 키) 는 관련된 윈도우의 자식 (객체) 로써, 사용자가 윈도우를 닫는다면 해당 바로가기 키도 마찬가지로 삭제가 됩니다.

QQuickItem, the basic visual element of the Qt Quick module, inherits from QObject, but has a concept of the visual parent which differs from that of the QObject parent. An item's visual parent may not necessarily be the same as its object parent. See Concepts - Visual Parent in Qt Quick for more details.

Qt Quick 모듈의 기본 시각 요소인 QQuickItem 은 QObject 로 부터 상속 받지만, QObject 부모의 것과 다른 시각적 부모의 개념을 가지고 있습니다. 한 아이템의 시각적 부모는 꼭 객체의 부모와 같을 필요는 없습니다. 자세한 내용은 Concepts - Visual Parent in Qt Quick (개념들 - Qt Quick 내의 시각적 부모) 을 참고 바랍니다.

QWidget, the fundamental class of the Qt Widgets module, extends the parent-child relationship. A child normally also becomes a child widget, i.e. it is displayed in its parent's coordinate system and is graphically clipped by its parent's boundaries. For example, when the application deletes a message box after it has been closed, the message box's buttons and label are also deleted, just as we'd want, because the buttons and label are children of the message box.

Qt Widget 모듈들의 근본 클래스인 QWidget 은 부모-자식 관계를 확장합니다. 자식은 보통 자식 위젯으로, 다시 말해 부모의 좌표 시스템 내에서 표시되고 부모의 경계 내에서 시각적으로 잡힙니다. 예를 들어, 응용프로그램은 대화상자가 닫힌 이후에 메시지를 삭제하는데, 메시지 박스의 자식 (개체) 들인 버튼들과 라벨들 또한 우리가 원하는데로 삭제가 됩니다.

You can also delete child objects yourself, and they will remove themselves from their parents. For example, when the user removes a toolbar it may lead to the application deleting one of its QToolBar objects, in which case the tool bar's QMainWindow parent would detect the change and reconfigure its screen space accordingly.

사용자는 또한 자식 객체들을 삭제할 수 있는데, 이 때는 삭제될 객체 자신이 부모 객체 간의 연결을 스스로 제거할 것입니다. 예들 들면, 사용자가 응용 프로그램에 연결되는 QToolBar 객체들의 하나를 삭제할 때, 이 경우 툴바의 QMainWindow 부모 (객체) 도 변화를 탐지하여 화면 공간을 재구성 할 것입니다.

The debugging functions QObject::dumpObjectTree() and QObject::dumpObjectInfo() are often useful when an application looks or acts strangely.

디버깅 함수들인 QObject::dumpObjectTree() 와 QObject:dumpObjectInfo() 는 응용 프로그램의 구조나 동작이 이상하게 보일 때 종종 유용하게 사용됩니다.

Construction/Destruction Order of QObjects

QObject 들의 생성/삭제 순서

When QObjects are created on the heap (i.e., created with new), a tree can be constructed from them in any order, and later, the objects in the tree can be destroyed in any order. When any QObject in the tree is deleted, if the object has a parent, the destructor automatically removes the object from its parent. If the object has children, the destructor automatically deletes each child. No QObject is deleted twice, regardless of the order of destruction.

QObject 들은 힙 (다시 말해 new 연산자를 써서 만들어 짐) 에서 생성될 때, 트리 정보가 어떤 순서를 통해 생성될 수 있고, 이후 트리 정보가 어떠한 순서로 제거가 될 수 있습니다. 만약 트리 정보내 QObject 가 삭제가 될때, 그 객체가 부모를 가지고 있다면, 파괴자는 자동으로 그 부모로 부터 해당 객체를 제거 합니다. 만약 그 객체가 자식들을 가지고 잇다면, 파괴자는 각각 자식들을 제거 할 것입니다. 어떠한 QObject 도 파괴의 순서와 관계없이 2번 삭제 되지 않습니다.

When QObjects are created on the stack, the same behavior applies. Normally, the order of destruction still doesn't present a problem. Consider the following snippet:

QObject 가 스택에서 만들어 질때, 같은 동작 방식이 적용됩니다. 보통 파괴의 순서는 문제를 발생하지 않습니다. 다음의 코드 스니펫을 생각해 봅시다.

int main()
{
    QWidget window;
    QPushButton quit("Quit", &window);
    ...
}

The parent, window, and the child, quit, are both QObjects because QPushButton inherits QWidget, and QWidget inherits QObject. This code is correct: the destructor of quit is not called twice because the C++ language standard (ISO/IEC 14882:2003) specifies that destructors of local objects are called in the reverse order of their constructors. Therefore, the destructor of the child, quit, is called first, and it removes itself from its parent, window, before the destructor of window is called.

부모인 window 그리고 자식인 quit 모두 QWidget 을 상속 받은 QPushButton 과 QObject 를 상속 받은 QWidget 이기 때문에, QObject 들입니다. 이 코드는 맞습니다. quit 의 파괴자는 C++ 언어 표준(ISO/IEC 14882:2003)에서 명시한 지역 객체들의 파괴자들은 그들의 생성자들의 호출 순서의 반대로 불려진다는 원칙에 따라 두번 불려지지 않습니다. 그러므로 자식인 quit 는 먼저 한번 불려지고 그 자신을 부모 객체인 window 의 파괴자가 제거되기 전에 window 로 부터 제거합니다.

But now consider what happens if we swap the order of construction, as shown in this second snippet:

하지만, 다음의 두번째 코드 스니펫 처럼 우리는 생성의 순서를 반대로 한다고 가정해 봅시다.

int main()
{
    QPushButton quit("Quit");
    QWidget window;

    quit.setParent(&window);
    ...
}

In this case, the order of destruction causes a problem. The parent's destructor is called first because it was created last. It then calls the destructor of its child, quit, which is incorrect because quit is a local variable. When quit subsequently goes out of scope, its destructor is called again, this time correctly, but the damage has already been done.

이 경우 파괴자의 순서는 문제를 발생 시킵니다. 부모의 파괴자는 객체가 마지막에 생성되었기 때문에 먼저 호출이 됩니다. 그리고 나서 그것은 자식 quit 의 파괴자를 호출하는데, 이것은 지역 변수이므로 부정확한 호출이 됩니다. quit 는 이후 Code 의 범위를 벗어나게 될 때 다시 파괴자가 호출되는데, 이 때는 시점은 정확하나, 이미 (파괴자에 의해) 손실을 입은 상태입니다.

© 2016 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.