메타 객체 시스템

Qt의 메타 객체 시스템은 객체 간 통신을 위한 시그널 및 슬롯 메커니즘, 런타임 타입 정보, 그리고 동적 속성 시스템을 제공합니다.

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

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

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

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

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

예를 들어, ` MyWidget `가 ` QWidget `를 상속받고 ` Q_OBJECT ` 매크로로 선언되었다고 가정해 봅시다:

    QObject *obj = new MyWidget;

QObject * 유형인 obj 변수는 실제로 MyWidget 객체를 가리키므로, 이를 적절하게 형변환할 수 있습니다:

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

QObject 에서 QWidget 로의 형변환이 성공하는 이유는, 해당 객체가 실제로 QWidget 의 하위 클래스인 MyWidget 이기 때문입니다. obj 가 MyWidget 임을 알고 있으므로, 이를 MyWidget * 로 형변환할 수도 있습니다:

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

MyWidget 으로의 형 변환이 성공하는 이유는 qobject_cast()가 내장 Qt 유형과 사용자 정의 유형을 구분하지 않기 때문입니다.

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

반면, QLabel 로의 형 변환은 실패합니다. 이때 포인터는 nullptr 로 설정됩니다. 이를 통해 실행 시점에 유형에 따라 서로 다른 유형의 객체를 다르게 처리할 수 있습니다:

    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 의 모든 하위 클래스는 실제로 신호(signals), 슬롯(slots), 속성(properties)을 사용하든 그렇지 않든 상관없이 Q_OBJECT 매크로를 사용할 것을 강력히 권장합니다.

QMetaObject, Qt의 속성 시스템( Property System), 신호 및 슬롯(Signals and Slots)항목도 참조하십시오 .

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