static_cast dynamic_cast cast c++ qt casting reinterpret-cast static-cast

c++ - dynamic_cast - ¿Cómo funciona qobject_cast?



cast c++ (1)

Esto es un poco complicado ...

Recuerde que qobject_cast<T>(obj) es una forma de lanzar dinámicamente un QObject al tipo de destino T que también se deriva de QObject . Ahora, para que esto funcione, la macro Q_OBJECT debe incluirse en la definición de clase T

Aparentemente, la llamada qt_check_for_QOBJECT_macro es para comprobar que la clase realmente contiene la macro Q_OBJECT. Cuando la macro se expande, contiene las siguientes definiciones:

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

Entonces, si tiene un objeto x de tipo T y un objeto y de tipo U , la llamada x->qt_check_for_QOBJECT_macro(y) llama a la función qYouForgotTheQ_OBJECT_Macro con parámetros de tipos T* y U* . Como la función se modela con un solo parámetro de tipo, los tipos T y U deben ser iguales.

Ahora, si llama a x->qt_check_for_QOBJECT_macro(x) entonces debe esperar que los tipos sean los mismos y que la compilación tenga éxito trivial. Sin embargo, recuerde que tiene el mismo tipo que la clase en la que se definió el método. Por lo tanto, si x es de una clase derivada de T pero no contiene su propia definición de qt_check_for_QOBJECT_macro , la llamada fallará.

Entonces, tenemos una forma de verificar si el tipo de destino T contiene el mecanismo correcto para el lanzamiento dinámico, pero no tenemos un objeto de tipo T para invocar este método aún. Para eso es reinterpret_cast<T>(0) . No necesitamos un objeto real como this , ya que el compilador solo necesita los tipos de objeto para que la verificación tenga éxito. En cambio, llamamos a un método en un puntero nulo de tipo T.

No creo que esto esté permitido por el estándar de C ++, pero funciona, ya que this no se usa realmente dentro del método.

Acabo de encontrar el siguiente código en Qt y estoy un poco confundido de lo que está sucediendo aquí.

Especialmente en lo que hace 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)))); }

¿Alguien quiere explicar?