Qobject_cast如何工作?
-
12-10-2019 - |
题
我刚刚在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*
. 。因为该函数用单个类型参数模板,所以类型 T
和 U
必须相同。
现在,如果您打电话 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
该方法内实际上没有使用。