[英]How does qobject_cast work?
我刚刚在Qt中找到了以下代码,我对这里发生的事情感到有些困惑。
特别是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
到目标类型T
,目标类型T
也是从QObject
派生的。 现在,为了使其工作,宏Q_OBJECT
应该包含在类T
的定义中。
显然, qt_check_for_QOBJECT_macro
调用用于检查该类是否确实包含Q_OBJECT宏。 扩展宏时,它包含以下定义:
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; }
因此,如果您有一个类型为T
的对象x
和一个类型为U
的对象y
,则调用x->qt_check_for_QOBJECT_macro(y)
调用函数qYouForgotTheQ_OBJECT_Macro
,其参数类型为T*
和U*
。 因为函数是使用单个类型参数模板化的,所以类型T
和U
必须相同。
现在,如果你调用x->qt_check_for_QOBJECT_macro(x)
那么你应该期望这些类型是相同的,并且编译可以简单地成功。 但是,请记住, this
与定义方法的类具有相同的类型。因此,如果x
是从T派生但不包含其自己的qt_check_for_QOBJECT_macro
定义的qt_check_for_QOBJECT_macro
,则调用将失败。
所以我们有办法检查目标类型T是否包含动态强制转换的正确机制,但我们还没有类型为T的对象来调用此方法。 这就是reinterpret_cast<T>(0)
的用途。 我们并不需要一个实际的对象为this
,因为编译器只需要对检查才能成功的对象类型。 相反,我们在类型为T的空指针上调用一个方法。
我不认为这是由C ++标准允许的,但它的作品,因为this
是不实际的方法内部使用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.