표준 C++의 관점에서 Qt 솔루션도 잘 작동합니다.
이
emit someSignal(3.14);
emit
키워드가 실제로 빈 #define
로 확인, 그래서 위의 라인은 메소드 지정된 인수와 someSignal
를 호출 신호를 방사하는
는 메소드를 호출하여 수행됩니다.
class SomeObject: public QObject {
Q_OBJECT
public slots:
void firstSlot() { /* implementation */ }
void secondSlot(double) { /* implementation */ }
signals:
void someSignal(double); /* no implementation here */
};
이 익숙 보인다해야 아직 신호의 실제 구현이 어디에서 오는지 당신이 궁금해 수 있습니다 방법은 지금처럼 QObject
유도 된 클래스 내에서 선언되었을 수 있습니다. . 당신이 추측 할 수 있듯이, Qt의 메타 오브젝트 컴파일러 (MOC가)에서 개막 곳이다 그것의 생성 된 소스에서 제공하는 signals
섹션 내를 선언 모든 방법에 대한 구현은 대략 다음과 같습니다이 :
void SomeObject::someSignal(double _t1)
{
void *_a[] = { Q_NULLPTR, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
QMetaObject::activate(this, &staticMetaObject, 1, _a);
}
흥미로운 부분은 void *_a[]
벡터이며,이 벡터는 신호에 전달 된 인수에 대한 포인터로 채워져 있습니다. 특히 여기에는 아무것도 없습니다.
인수 벡터는 QMetaObject::activate
으로 전달되고 스레드 안전 검사 및 기타 관리 작업을 수행 한 다음 신호에 연결된 슬롯을 호출하기 시작합니다. 런타임에 신호 대 슬롯 연결이 해결되면 (connect()
작동 방식) MOC의 도움이 필요합니다. 특히, MOC는 또한 qt_static_metacall()
구현 클래스를 생성
void SomeObject::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
SomeObject *_t = static_cast<SomeObject *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->firstSlot(); break;
case 1: _t->secondSlot((*reinterpret_cast< double(*)>(_a[1]))); break;
default: ;
}
} /* some more magic */
}
당신이 볼 수 있듯이,이 방법은 함수 호출에 전에에서 void *_a[]
벡터를 해결하기 위해 다른 쪽 끝을 포함한다. 또한 가변 인수 목록 (줄임표 사용, ...
) 또는 다른 의심스러운 속임수가없는 것을 볼 수 있습니다.
그래서 원래 질문을 계몽하는 것이 좋습니다.someSignal(double)
이 신호의 서명과 일치하는 secondSlot(double)
에 연결되면 qt_static_metacall
에있는 case 1
으로 전화가 연결되고 예상대로 인수가 전달됩니다.
신호보다 더 적은 인수를 가진 firstSlot()
에 신호를 연결할 때, 호출은 case 0
으로 해결되고 인수없이 firstSlot()
이 호출됩니다. 신호에 전달 된 인수는 void *_a[]
벡터에서 그대로 유지됩니다.
또한 C++ 표준을 준수합니까, 아니면 Qt 당 작동하도록 보장되는 기능입니까? 적어도 평범한 C에서는 ISO/IEC 9899 : TC2 §6.5.2.2p6을 통해 UB로 연결됩니다. – Kamajii
@Kamajii : 슬롯 호출은 직접 함수 호출이 아닙니다. UB가 없으므로 Qt는 함수를 올바르게 호출합니다. – Mat
물론 정규 호출 (+ 대기열에있는 연결 등) 만 슬롯 호출입니다. 신호 방출이 마침내 자동 생성 된 (moc)'qt_static_metacall '멤버에 도달하면 매우 문제가 발생합니다. – Kamajii