Q_OBJECT
매크로는 신호 및 슬롯과 관련하여 나중에 moc
으로 정의 될 클래스의 선언에 가상 함수 qt_metacall()
선언을 추가합니다. (또한 변환에 대한 몇 가지 선언을 추가하지만 여기에 너무 중요하지 않아.)
moc
는 헤더 파일을 읽어 들여, 매크로를 볼 때, 그것은 가상 기능에 대한 정의를 moc_headerfilename.cpp
라는 이름의 또 다른 .cpp
파일을 생성합니다 - 당신은 왜 당신이 신호의 적절한 정의없이 signals:
을 당신의 헤더 파일에 언급하는 것으로 벗어날 수 있는지 스스로에게 물어볼 것입니다.
그래서 신호가 호출되면 mocfile의 정의가 실행되고 QMetaObject::activate()
이 신호의 이름과 신호의 인수로 호출됩니다. 그러면 activate()
함수는 어떤 연결이 설정되었는지 알아 내고 해당 슬롯의 이름을 가져옵니다. 실제 슬롯 case
문 -
는 그 다음 슬롯 이름과 신호와 큰 switch
의 도움으로 metacall 기능 위임이 주어진 인수 qt_metacall
를 호출합니다.
신호 슬롯의 실제 이름에 관한 C 가능한 실제 런타임 정보 ++ 없기 때문에, 이미 발견 한 바와 같이, 이들은 하나를 "1"로 (단순 const char*
들에 SIGNAL
및 SLOT
매크로에 의해 인코딩 될 슬롯과 신호를 구별하기 위해 이름에 "2"가 추가됨).
으로는 qobjectdefs.h
에 정의되어
#define SLOT(a) "1"#a
#define SIGNAL(a) "2"#a
-
Q_OBJECT
매크로 응용 프로그램을 번역하는 데 사용할 수있는 개체 내부의 tr()
기능을 정의하고 수행하는 다른 것은.
편집 당신이 qt_metacast
가 무엇을하고 있는지 질문한다. 객체가 특정 클래스에 속하는지 여부를 확인하고 포인터가 해당 객체에 포인터를 반환하는지 여부를 확인합니다. 그렇지 않으면 0을 반환합니다.
Widget* w = new Widget();
Q_ASSERT(w->qt_metacast("Widget") != 0);
Q_ASSERT(w->qt_metacast("QWidget") != 0);
Q_ASSERT(w->qt_metacast("QObject") != 0);
Q_ASSERT(w->qt_metacast("UnrelatedClass") == 0);
이렇게하면 달리 반영 할 수없는 런타임 리플렉션을 제공해야합니다. 예를 들어,이 함수는 QObject::inherits(const char *)
에서 호출되고 단순히 상속을 확인합니다.
dup : http://stackoverflow.com/questions/1406940/how-signal-and-slots-are-implemented-under-the-hood – elcuco