繁体   English   中英

qobject_cast如何工作?

[英]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* 因为函数是使用单个类型参数模板化的,所以类型TU必须相同。

现在,如果你调用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM