qobject_cast如何工作?
我刚刚在Qt中find下面的代码,我有点困惑这里发生了什么。
特别是对于reinterpret_cast<T>(0)
是什么?
template <class T> inline T qobject_cast(const QObject *object) { // this will cause a compilation error if T is not const register T ptr = static_cast<T>(object); Q_UNUSED(ptr); #if !defined(QT_NO_MEMBER_TEMPLATES) && !defined(QT_NO_QOBJECT_CHECK) reinterpret_cast<T>(0)->qt_check_for_QOBJECT_macro(*reinterpret_cast<T>(const_cast<QObject *>(object))); #endif return static_cast<T>(const_cast<QObject *>(reinterpret_cast<T>(0)->staticMetaObject.cast(const_cast<QObject *>(object)))); }
任何人都在意解释?
这有点复杂
请记住, qobject_cast<T>(obj)
是一种将QObject
dynamic转换为也从QObject
派生的目标typesT
。 现在,为了这个工作,macrosQ_OBJECT
应该被包括在类T
的定义中。
显然, qt_check_for_QOBJECT_macro
调用用于检查类是否真的包含Q_OBJECTmacros。 当macros展开时,它包含以下定义:
template <typename T> inline void qt_check_for_QOBJECT_macro(const T &_q_argument) const { int i = qYouForgotTheQ_OBJECT_Macro(this, &_q_argument); i = i; } template <typename T1, typename T2> inline int qYouForgotTheQ_OBJECT_Macro(T, T) { return 0; }
所以如果你有一个types为T
的对象x
和一个types为U
的对象y
,调用x->qt_check_for_QOBJECT_macro(y)
调用带有types为T*
和U*
参数的函数qYouForgotTheQ_OBJECT_Macro
。 由于该函数是使用单个types参数模板化的,因此typesT
和U
必须相同。
现在,如果你调用x->qt_check_for_QOBJECT_macro(x)
那么你应该期望types是相同的,并且编译才能成功。 但是,请记住, this
与定义方法的类具有相同的types。因此,如果x
是从T派生的类,但不包含自己的qt_check_for_QOBJECT_macro
定义,则调用将失败。
所以我们有一种方法来检查目标typesT是否包含dynamic转换的正确机制,但是我们还没有typesT的对象来调用这个方法。 这就是reinterpret_cast<T>(0)
的用途。 我们不需要一个实际的对象,因为编译器只需要检查的对象types成功。 相反,我们调用一个types为T的空指针的方法。
我不认为这是C ++标准所允许的,但是它起作用,因为this
在方法内部没有实际使用。