【问题标题】:How does qobject_cast work?qobject_cast 是如何工作的?
【发布时间】:2011-05-29 22:10:39
【问题描述】:

我刚刚在 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))));
}

有人愿意解释一下吗?

【问题讨论】:

    标签: c++ qt casting reinterpret-cast static-cast


    【解决方案1】:

    这有点复杂……

    请记住,qobject_cast&lt;T&gt;(obj) 是一种将QObject 动态转换为目标类型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-&gt;qt_check_for_QOBJECT_macro(y) 会调用具有T* 和@987654338 类型参数的函数qYouForgotTheQ_OBJECT_Macro @。因为该函数是使用单个类型参数模板化的,所以类型 TU 必须相同。

    现在,如果您调用x-&gt;qt_check_for_QOBJECT_macro(x),那么您应该期望类型相同并且编译会轻松成功。但是,请记住 this 与定义该方法的类具有相同的类型。因此,如果 x 是从 T 派生但不包含其自己的 qt_check_for_QOBJECT_macro 定义的类,则调用将失败。

    所以我们有办法检查目标类型 T 是否包含正确的动态转换机制,但是我们还没有类型 T 的对象来调用此方法。这就是reinterpret_cast&lt;T&gt;(0) 的用途。我们不需要像this 这样的实际对象,因为编译器只需要对象类型就可以成功检查。相反,我们在 T 类型的空指针上调用方法。

    我认为 C++ 标准不允许这样做,但它可以工作,因为 this 实际上并未在方法中使用。

    【讨论】:

    • 您能否澄清一下您认为 C++ 标准不允许的部分?我很好奇。
    • 该方法是静态的,它不被称为“on”指针。 this 将引用调用者而不是不存在的对象。
    • Now, for this to work, the macro Q_OBJECT should be included in the definition of class T. 这可能是错误的。 Qt 文档hereWhile it is possible to use QObject as a base class without the Q_OBJECT macro and without meta-object code, neither signals and slots nor the other features described here will be available if the Q_OBJECT macro is not used.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-27
    • 1970-01-01
    • 2017-07-24
    • 2016-11-13
    • 2017-10-11
    • 2021-10-13
    相关资源
    最近更新 更多