我刚刚在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 也源于 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; }

因此,如果您有一个对象 x 类型 T 和一个对象 y 类型 U, ,电话 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, ,通话将失败。

因此,我们有一种方法可以检查目标t型是否包含了动态铸件的正确机制,但是我们没有T型对象可以调用此方法。那就是 reinterpret_cast<T>(0) 是。我们不需要实际的对象 this, ,由于编译器仅需要对象类型才能成功。相反,我们调用Type T型的空指针上的方法。

我认为C ++标准不允许这样做,但是它起作用了 this 该方法内实际上没有使用。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top