메타 객체 시스템

Qt의 메타 객체 시스템은 객체 간 통신을 위한 신호와 슬롯 메커니즘, 런타임 타입 정보, 동적 프로퍼티 시스템을 제공합니다.

메타 객체 시스템은 세 가지를 기반으로 합니다:

  1. QObject 클래스는 메타 객체 시스템을 활용할 수 있는 객체를 위한 베이스 클래스를 제공합니다.
  2. Q_OBJECT 매크로는 동적 속성, 신호 및 슬롯과 같은 메타 객체 기능을 활성화하는 데 사용됩니다.
  3. 메타 객체의 Meta-Object Compiler (moc)는 각 QObject 하위 클래스에 메타 객체 기능을 구현하는 데 필요한 코드를 제공합니다.

moc 도구는 C++ 소스 파일을 읽습니다. Q_OBJECT 매크로가 포함된 클래스 선언을 하나 이상 발견하면 각 클래스의 메타 객체 코드가 포함된 또 다른 C++ 소스 파일을 생성합니다. 이렇게 생성된 소스 파일은 클래스의 소스 파일에 #include'd되거나, 더 일반적으로는 컴파일되어 클래스 구현과 링크됩니다.

메타 객체 코드는 객체 간 통신을 위한 신호 및 슬롯 메커니즘(시스템 도입의 주된 이유)을 제공하는 것 외에도 다음과 같은 추가 기능을 제공합니다:

QObject 클래스에서 qobject_cast()를 사용하여 동적 형변환을 수행할 수도 있습니다. qobject_cast () 함수는 표준 C++ dynamic_cast() 과 유사하게 동작하며, RTTI 지원이 필요하지 않고 동적 라이브러리 경계를 넘나들며 작동한다는 장점이 있습니다. 이 함수는 인수를 꺾쇠 괄호 안에 지정된 포인터 유형으로 캐스팅하여 객체가 올바른 유형(런타임에 결정됨)인 경우 0이 아닌 포인터를 반환하고, 객체의 유형이 호환되지 않는 경우 nullptr 을 반환합니다.

예를 들어 MyWidgetQWidget 에서 상속되고 Q_OBJECT 매크로로 선언되었다고 가정해 보겠습니다:

    QObject *obj = new MyWidget;

QObject * 유형의 obj 변수는 실제로 MyWidget 객체를 참조하므로 적절하게 형변환할 수 있습니다:

    QWidget *widget = qobject_cast<QWidget *>(obj);

QObject 에서 QWidget 으로의 형변환은 성공합니다. 왜냐하면 이 객체는 실제로 QWidget 의 서브클래스인 MyWidget 이기 때문입니다. objMyWidget 라는 것을 알고 있으므로 MyWidget * 로도 형변환할 수 있습니다:

    MyWidget *myWidget = qobject_cast<MyWidget *>(obj);

qobject_cast()은 내장형과 사용자 정의형을 구분하지 않기 때문에 MyWidget 로의 형변환은 성공합니다.

    QLabel *label = qobject_cast<QLabel *>(obj);
    // label is 0

반면 QLabel 로의 형변환은 실패합니다. 그러면 포인터가 0으로 설정됩니다. 이렇게 하면 런타임에 유형에 따라 서로 다른 유형의 객체를 다르게 처리할 수 있습니다:

    if (QLabel *label = qobject_cast<QLabel *>(obj)) {
        label->setText(tr("Ping"));
    } else if (QPushButton *button = qobject_cast<QPushButton *>(obj)) {
        button->setText(tr("Pong!"));
    }

Q_OBJECT 매크로 없이 메타 객체 코드 없이 QObject 을 기본 클래스로 사용할 수 있지만, Q_OBJECT 매크로를 사용하지 않으면 신호와 슬롯이나 여기에 설명된 다른 기능을 사용할 수 없습니다. 메타 객체 시스템의 관점에서 볼 때 메타 코드가 없는 QObject 서브클래스는 메타 객체 코드가 있는 가장 가까운 조상과 동일합니다. 예를 들어 QMetaObject::className()는 실제 클래스 이름이 아니라 이 조상의 클래스 이름을 반환한다는 의미입니다.

따라서 QObject 의 모든 하위 클래스는 신호, 슬롯 및 속성을 실제로 사용하는지 여부에 관계없이 Q_OBJECT 매크로를 사용할 것을 강력히 권장합니다.

QMetaObject, Qt의 프로퍼티 시스템, 시그널과 슬롯도참조하십시오 .

© 2025 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.