qobject_cast如何工作?

我刚刚在Qt中find下面的代码,我有点困惑这里发生了什么。

特别是对于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)是一种将QObjectdynamic转换为也从QObject派生的目标typesT 。 现在,为了这个工作,macrosQ_OBJECT应该被包括在类T的定义中。

显然, qt_check_for_QOBJECT_macro调用用于检查类是否真的包含Q_OBJECTmacros。 当macros展开时,它包含以下定义:

 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; } 

所以如果你有一个types为T的对象x和一个types为U的对象y ,调用x->qt_check_for_QOBJECT_macro(y)调用带有types为T*U*参数的函数qYouForgotTheQ_OBJECT_Macro 。 由于该函数是使用单个types参数模板化的,因此typesTU必须相同。

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

所以我们有一种方法来检查目标typesT是否包含dynamic转换的正确机制,但是我们还没有typesT的对象来调用这个方法。 这就是reinterpret_cast<T>(0)的用途。 我们不需要一个实际的对象,因为编译器只需要检查的对象types成功。 相反,我们调用一个types为T的空指针的方法。

我不认为这是C ++标准所允许的,但是它起作用,因为this在方法内部没有实际使用。