728x90
반응형
728x90
반응형
728x90
반응형

QObject Casting (qobject_cast)

I. 소개

  • Qt 는 QObject 를 부모 클래스로 하는 클래스를 생성하는 방법으로 메타 오브젝트 프로그래밍을 지원합니다.
  • Qt 를 처음 사용하시는 분은 QObject의 구조나 사용 방법이 번잡하고 불필요한 것으로 느껴질 수도 있습니다.
  • 하지만 Qt 를 제대로 사용하는 방법 중 하나는 QObject를 상속한 클래스를 만드는 것입니다.
    • 물론 C++ 표준안(최근)의 방법만으로도 메타 오브젝트 프로그래밍은 가능합니다.

II. 예제

 1: // class MyWidget : public QWidget
 2:  
 3: QObject *obj = new MyWidget; 
 4: 
 5: QWidget *widget = qobject_cast<QWidget *>(obj); 
 6: Q_ASSERT( widget != NULL );
 7:
 8: MyWidget *myWidget = qobject_cast<MyWidget *>(obj); 
 9: Q_ASSERT( myWidget != NULL );
10:
11: QLabel *label = qobject_cast<QLabel *>(obj);
12: Q_ASSERT( label != NULL ); // label is 0(NULL). because obj is not inherited from QLabel.
  • 예제는 QObject 캐스팅(qobject_cast)을 활용하는 방법입니다.
  • 이는 C++의 dynamic cast와 유사합니다.
  • 부모 클래스가 누구인지를 기록하고 있으며, 조상들이 많은 경우 이 방법은 더욱 진가를 발휘합니다.
  • 객체지향 프로그램에서 상속은 많은 단계를 하지 말라는 권장사항이 있습니다만, 이는 어떻게 만드는 가에 따라 권장이 아닐수 도 있다는 점은 명심하여야 합니다.

III. 예제 설명

  • 예제를 봅시다.
  • 클래스 MyWidget 는 QWidget 을 부모 클래스로 상속합니다. class MyWidget : public QWidget
  • 그리고 예제에 코드는 없지만 QWidget 는 QObject 를 상속하고 있습니다.
  • 5번 라인을 보면 객체 포인터 obj 는 QWidget 포인터로 캐스팅하고 있습니다. QWidget *widget = qobject_cast<QWidget *>(obj);
  • dynamic cast 방식이 아닌 일반적인 C++ 캐스팅으로는, 상속관계를 무시하고 캐스팅을 하므로 위험요소를 가지고 있습니다.
  • 하지만 qobject_cast 를 사용하면 캐스팅시 점검을 수행하여 줍니다.

IV. 추가 설명

  • 예제 11번 라인을 보면 상속관계가 전혀 없는 QLabel 로 캐스팅하는 것을 볼 수 있습니다. QLabel *label = qobject_cast<QLabel *>(obj);
  • 이런 경우 label 은 0zero의 값을 반환하고 이는 C++의 NULLnullptr과 동일값 입니다.
  • 물론 12번 라인의 assert()를 통하여 잘못된 캐스팅을 미리 알아낼 수 있습니다. Q_ASSERT( label != NULL );
728x90
반응형

+ Recent posts